using #FILE in forfiles not working - command-line

I am trying to build a batch file that deletes all excel files older than 30 days. So far I have the command:
forfiles -p"N:\QC\ATR's" -s -m*.xls* -d-30 -c"CMD /C del /f /q #FILE"
The only problem seems to be the fact that #FILE has a space in the folder/file name so the del command cannot find the specified path. For example, looking at the echoes from the command it says
Could Not Find N:\QC\ATR's\'-5
When it should really be looking for the path
N:\QC\ATR's\-5 brightness study
See what I mean? Is there a way to tell the #FILE variable to be wrapped in quotes or something?
Thanks

You could try the following:
SET FILE = -5 brightness study
forfiles -p"N:\QC\ATR's" -s -m*.xls* -d-30 -c"CMD /C del /f /q %FILE%"
Check these sites for some assistance:
http://ss64.com/nt/path.html
http://www.windowsitpro.com/article/server-management/how-do-i-pass-parameters-to-a-batch-file-

I figured it out. I just added Hex coded qoutes around the file variable
forfiles -p"N:\QC\ATR's" -s -m*.xls* -d-30 -c"CMD /C del /f /q ^0x22#FILE^0x22"

Related

How to take output of dir search and modify specified file

I'm trying to use this script to assist technicians with renaming files that are found on an end users computer within their %appdata% folder. The script works up until this point, but I can't figure out how to take the output of the DIR search to use it as the current directory so I can modify the destination folder.
Basically, I need to make changes to this folder:
C:\users\bob\appdata\local\apps\2.0\'7'\'7'\time...exe_bfe88f94fc69adaa_0005.0011_none_b883acbb6e8d0075
The two 7's or wildcards are always different folder directory names, so that's why I can't use a static path to make changes to these folders. Anyways, here is the script so far, it works just fine in locating the folder I need, but I cannot seem to use the output to specify it as the target so I can make changes to it. Thank you for your help.
cd %appdata%
cd ..
cd local\apps\2.0
dir "time...exe_bfe88f94fc69adaa_0005.0011_none_39f58db4ac6311ec" /ad /s
I've tried using the pipeline argument (|) and the '&' and then using a rename command or a removedir, but it cannot find the file specified.
Thank you for your help!
Here's a batch-file which is a little more direct than just recursing the entire tree. It only steps over the two 'unknown' directory names, (%%~nxG\%%~nxH), and checks there for the named directory, (which you should edit as needed on line 3):
#Echo Off & SetLocal EnableExtensions
Set "DirName=time...exe_bfe88f94fc69adaa_0005.0011_none_39f58db4ac6311ec"
Set "BaseDir=%LocalAppData%\apps\2.0"
Set "AppPath="
For /D %%G In ("%BaseDir%\*")Do For /D %%H In ("%%G\*")Do For %%I In (
"%%H\%DirName%")Do If "%%~aI" GEq "d" Set "AppPath=%%~I"
If Not Defined AppPath Echo %DirName% Not Found & Pause & Exit /B 1
Echo %%AppPath%% = %AppPath% & Pause
Nothing else should be modified except for the last line which I added just to provide some output, (you/your technicians would use "%AppPath%" to reference the target directory from that point forward).
If you were looking for something in powershell, then perhaps this will push you in the right direction:
$DirName = "time...exe_bfe88f94fc69adaa_0005.0011_none_39f58db4ac6311ec"
$AppPath = (RvPa "$Env:LocalAppData\apps\2.0\*\*\$DirName").Path
$AppPath
Once again the last line is just to provide output and show you the variable you'll need to reference your target directory, and the first line will need editing as needed.
This code uses a FOR loop to find directory names that match. There is an ECHO inside the loop since I do not know if multiple directories could be found.
#ECHO OFF
CD "%APPDATA%\.."
FOR /F "delims=" %%A IN ('DIR /S /B /A:D "time...exe_bfe88f94fc69adaa_0005.0011_none_39f58db4ac6311ec"') DO (
ECHO Found directory "%%~A"
SET THEDIR=%%~A
)
DIR "%THEDIR%"
REN "%THEDIR%\file1.txt" "file2.txt"

How to write STDOUT/STDIN via RedMon/cmd.exe to file?

I am trying to redirect a PS output to a file and process it further.
For this I am using the Printer Port Redirection RedMon which is sending the output to CMD.exe
C:\Windows\system32\cmd.exe
As arguments I expected that something like the following should work, but it does not. "%1" contains the user input for filename.
/c >"%1"
or
/c 1>"%1"
or
/c |"%1"
or
/c > "%1" 2>&1
What almost works if I send the output to a batch file which writes it then to file.
/c WriteOutput.bat "%1"
However, the batch file is somehow altering the file (skipping empty lines, and ignoring exclamation marks and so on...)
If possible I want to avoid a batch file. Is there a way to get it "directly" to a file?
Select "Print to FILE" in the printer options is not an option for me. I want the same end result but via cmd.exe being able to process it further.
Any ideas?
Edit:
Well, that's the batch file I used. It neglects empty lines and space at the beginning.
#echo off
setlocal
set FileName=%1
echo(>%FileName%.ps
for /F "tokens=*" %%A in ('more') do (
echo %%A>>%FileName%.ps
)
Well, so far I still haven't found a direct way to write STDIN via RedMon via CMD.exe to a file. As #aschipfl wrote, all the versions with for /F will skip lines and ignore certain characters.
However, with the following batch script (via RedMon) I end up with a "correct looking" file on disk.
C:\Windows\system32\cmd.exe /c WritePS.bat "%1"
"%1" contains the user input for filename without extension.
The Batch-File WritePS.bat looks as simple as this:
#echo off & setlocal
set FileName=%1.ps
more > "%FileName%"
However,
the resulting Postscript file is different from a file which I "Print to FILE" via the Postscript-Printer setup. I am pretty sure that all the printer settings which I can set are the same in both cases.
If anybody has an idea why there might be a difference, please let me know.

PSCP automatic upload newest file

I am trying to make a bat script that uploades the newest file from a folder to the public html. How to do this? I got this to work at the moment.
c:pscp -pw password c:\index.html user#host:public_html/index.html
Got it:
set source="C:\dir"
FOR /F "delims=|" %%I IN ('DIR %source% /B /O:D') DO SET NewestFile=%%I
c:pscp -pw password %source%\%NewestFile% user#host:public_html/%NewestFile%
pause

7zip command line synthax using wildcard

Based on this source, the following should work for the 7zip command line tool:
7zG a -tzip "C:\20131024_archive.zip" "C:\archive" *20131024*
The goal is to zip all the files containing the date in the name. However, this is not working for me as it zips all the files without the date filter.
I've tried all sorts of variants without success. What am I doing wrong?
It turns out the date filter goes into the target filename like so:
7zG a -tzip "C:\20131024_archive.zip" "C:\archive\*20131024*"
Just use forfiles if your using windows 7. Type forfiles /? for more info. A think this will do what you want:
pushd C:\archive
forfiles /m "*20131024*" /c "7zG a -tzip C:\20131024_archive.zip #file"
I'm not sure this will work if the file name has spaces.

XCOPY switch to create specified directory if it doesn't exist?

I am using XCOPY in a post-build event to copy compiled DLLs from their output folders to the main app's output folder. The DLLs are being copied to a "Modules" subfolder in the main app output folder, like this:
xcopy "$(TargetPath)" "$(SolutionDir)Prism4Demo.Shell\$(OutDir)Modules\"
The command works fine if the Modules folder exists, but I have discovered during testing that if the folder doesn't exist, XCOPY doesn't create it, and the command fails.
Is there an XCOPY switch that will cause the folder to be created if it doesn't exist? If not, what would I add to my post-build event to create the folder if it doesn't exist? Thanks for your help.
Answer to use "/I" is working but with little trick - in target you must end with character \ to tell xcopy that target is directory and not file!
Example:
xcopy "$(TargetDir)$(TargetName).dll" "$(SolutionDir)_DropFolder" /F /R /Y /I
does not work and return code 2, but this one:
xcopy "$(TargetDir)$(TargetName).dll" "$(SolutionDir)_DropFolder\" /F /R /Y /I
Command line arguments used in my sample:
/F - Displays full source & target file names
/R - This will overwrite read-only files
/Y - Suppresses prompting to overwrite an existing file(s)
/I - Assumes that destination is directory (but must ends with \)
I tried this on the command line using
D:\>xcopy myfile.dat xcopytest\test\
and the target directory was properly created.
If not you can create the target dir using the mkdir command with cmd's command extensions enabled like
cmd /x /c mkdir "$(SolutionDir)Prism4Demo.Shell\$(OutDir)Modules\"
('/x' enables command extensions in case they're not enabled by default on your system, I'm not that familiar with cmd)
use
cmd /?
mkdir /?
xcopy /?
for further information :)
I hate the PostBuild step, it allows for too much stuff to happen outside of the build tool's purview. I believe that its better to let MSBuild manage the copy process, and do the updating. You can edit the .csproj file like this:
<Target Name="AfterBuild" Inputs="$(TargetPath)\**">
<Copy SourceFiles="$(TargetPath)\**" DestinationFiles="$(SolutionDir)Prism4Demo.Shell\$(OutDir)Modules\**" OverwriteReadOnlyFiles="true"></Copy>
</Target>
Use the /i with xcopy and if the directory doesn't exist it will create the directory
for you.
You could use robocopy:
robocopy "$(TargetPath)" "$(SolutionDir)Prism4Demo.Shell\$(OutDir)Modules" /E
Simple short answer is this:
xcopy /Y /I "$(SolutionDir)<my-src-path>" "$(SolutionDir)<my-dst-path>\"
Simply type in quotes slash delimiter "/" and add to final destination 2 back-slashes "\\"
It's will be create New folders to copy and copy need file(-s).
xcopy ".\myfile" "....folder1/folder2/destination\\"
I tried this on the command.it is working for me.
if "$(OutDir)"=="bin\Debug\"  goto Visual
:TFSBuild
goto exit
:Visual
xcopy /y "$(TargetPath)$(TargetName).dll" "$(ProjectDir)..\Demo"
xcopy /y "$(TargetDir)$(TargetName).pdb" "$(ProjectDir)..\Demo"
goto exit
:exit
Try /E
To get a full list of options: xcopy /?