#ECHO OFF
Set LOG="C:\Temp\Copy.log"
::########################
:: Begin copying
::########################
Set Sourcedir="c:\data\PRODDB\dir"
Set Targetdir="C:\test"
Echo %date% %time%: "Copying from %sourcedir% to %Targetdir%" >> %LOG%
Forfiles /P "%Sourcedir%" /D +0 /C "cmd /c copy #path "%Targetdir%" >> %LOG%
when i execute the above script ,i am getting the below error ERROR: Invalid argument/option - '>>'.
Type "FORFILES /?" for usage. what could be the issue here ? thanks
the problem is on the /C parameter. You don't close your double quotes correctly.
try
Forfiles /P "%Sourcedir%" /D +0 /C "cmd /c copy #path %Targetdir%" >> %LOG%
Both PA's answer and aphoria's answer will work in most cases. But they will fail if the Targetdir contains token delimiters like <space>, =, ;, etc. or poison characters like &. Quotes are needed in such cases. Aphoria's answer looks like it might work, but the extra quotes cause Targetdir to not be quoted in the first parsing pass.
The solution is to use the FORFILES 0xNN notation to represent the internal quotes.
Forfiles /P "%Sourcedir%" /D +0 /C "cmd /c copy #path 0x22%Targetdir%0x22" >> %LOG%
You're missing a quote at the end of your command
Try this:
Forfiles /P "%Sourcedir%" /D +0 /C "cmd /c copy #path "%Targetdir%"" >> %LOG%
Note the "" just before the >>.
Related
I'm stuck with this script
echo off
SET pathAdobe="C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe"
SET pathDestination=T:\
cd %pathDestination%
(1)
forfiles /P %pathDestination% /M *8.pdf /D +0 /C "cmd /c echo #PATH"
(2)
"C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe" /o /h /s /t "%pathDestination%\pdf8.pdf" "MyPrinterName"
pause
(1) Work fine, i got a list of pdf according my forfiles
(2) Work fine, print my file
(3) But when i want to mix the 2 first step that doesn't work like i want
forfiles /P %pathDestination% /M *8.pdf /D +0 /C "CMD /C "%pathAdobe%" /o /h /s /t #PATH"
I got this error:
Error: Invalid argument or option - « Files\Adobe\Acrobat »
I try to escape with ^ " \ but don't change the result
Can't find a solution!
Thanks for any help you can give me :)
J
Your issue is that you are including double quotes, in the wrong places, and that those double quotes require escaping. You can escape those using backward slashes (\"), or by using their hexadecimal character code, (0x22).
Backward slash example:
#Echo Off
Set "pathAdobe=%ProgramFiles%\Adobe\Acrobat DC\Acrobat\Acrobat.exe"
Set "pathDestination=T:\"
CD /D "%pathDestination%" 2> NUL || Exit /B
%SystemRoot%\System32\forfiles.exe /M "*8.pdf" /D 0 /C "%SystemRoot%\System32\cmd.exe /D /C \"\"%pathAdobe%\" /o /h /s /t #Path \"MyPrinterName\"\""
Pause
Hexadecimal character example:
#Echo Off
Set "pathAdobe=%ProgramFiles%\Adobe\Acrobat DC\Acrobat\Acrobat.exe"
Set "pathDestination=T:\"
CD /D "%pathDestination%" 2> NUL || Exit /B
%SystemRoot%\System32\forfiles.exe /M "*8.pdf" /D 0 /C "%SystemRoot%\System32\cmd.exe /D /C 0x220x22%pathAdobe%0x22 /o /h /s /t #Path 0x22MyPrinterName0x220x22"
Pause
I need to get a list of empty folders in a given location, older then x days. Using "forfiles" I'm able to get all older folders, but not the empty ones. Using "for" I'm able to get all empty folders, but I can't seem to set the older ones.
Get empty folders:
#for /r "c:\FileStore" /d %F in (.) do #(dir /b "%F" | findstr "^" >nul || echo %~fF)
Get older folders:
ForFiles /p "C:\FileStore" /s /d -3 /c "cmd /c if #isdir==TRUE echo #path"
How do I combine these 2 commands?
You need to escape the quotation marks of the part findstr "^" for forfiles. There is the way \", but I do not recommend this, because the " are still recognised by the command interpreter cmd (user Ben Personick shows how to do this in his answer though). Anyway, I would use 0x22 instead in order to hide the quotes from cmd, like this:
forfiles /S /P "C:\FileStore" /D -3 /C "cmd /C if #ISDIR == TRUE (dir /B /A #PATH | findstr 0x22^0x22 > nul || echo #PATH)"
Instead of findstr "^" you could also use find /V "":
forfiles /S /P "C:\FileStore" /D -3 /C "cmd /C if #ISDIR == TRUE (dir /B /A #PATH | find /V 0x220x22 > nul || echo #PATH)"
But the easiest way is to use set /P:
forfiles /S /P "C:\FileStore" /D -3 /C "cmd /C if #ISDIR == TRUE (dir /B /A #PATH | set /P _= || echo #PATH)"
N. B.:
forfiles only regards the date (not the time) of the last modification, but not the creation date/time.
Your biggest hurdle is escaping the double quotes in the FindStr and the Carrot needing doubling too (or it will stop the following quote from being escaped.)
Hmm strange I thought you asked to delete these directories, since you haven't I'll amend it as such.
ForFiles /P "c:\FileStore" /d -3 /C "CMD /C if #isdir==TRUE ( DIR /B #Path | FindStr \"^^\" >NUL || ECHO Empty Folder: #Path )"
Also since you are only looking for a list of those it does make sense to kill the output from the FindStr so I added the >Nul back in.
Again not sure how I ot it into my head that you wanted to remove the empty folders older than 3 days old, since there isn't such a requirement, the portion about needing to re-run the command is moot and I've remove dit for now.
I want to try the bat file to copy my log to other space.
My code:
REM get date
FOR /F "tokens=1-4 delims=/ " %%a IN ("%date%") DO (SET _MyDate=%%d/%%b/%%c)
echo _MyDate: %_MyDate%
set _path= "D:\Logs\AddressBook Service"
set _path2= "E:\Logs_test\AddressBook Service"
forfiles /p %_path% /d -%_day% /m *.log /c "cmd /c xcopy #path %_path2%"
My question is How to solve the forfiles #path has spaces in folder path?
Like this: E:\Logs_test\AddressBook Service
set "_day=2" only my guess
set "_path=D:\Logs\AddressBook Service"
set "_path2=E:\Logs_test\AddressBook Service"
forfiles /p "%_path%" /d -%_day% /m *.log /c "cmd /c echo xcopy #path \"%_path2%\\\" /D /E /-Y"
Above code snippet with proper escaped " double quotes (surprisingly escaped using a backslash \" instead of common caret) should result in something like
xcopy "D:\Logs\AddressBook Service\some name.log" "E:\Logs_test\AddressBook Service\" /D /E /-Y
Note that operational xcopy is merely displayed for debugging purposes. Remove echo keyword no sooner than debugged.
Adding a trailing backslash to xcopy target folder (%_path2%\\) seems to be facultative (optional) supplement.
Finally, note double quotes in set "variablename=variable value" syntax.
The forfiles command establishes several variables, indicated by a leading #, which return data concerning the currently iterated item to the loop body.
All the variables related to the path and name of the iterated item return the value enclosed in "". Those are: #file, #fname, #ext, #path and #relpath.
So: how can you get rid of the enclosing double-quotes?
For example, the following code returns relative paths to text files in the given root directory:
forfiles /P "C:\root" /M "*.txt" /C "cmd /C echo #relpath"
Assuming that C:\root contains two files file1.txt and file2.txt, the output will be:
".\file1.txt"
".\file2.txt"
However, I want the list of files without the surrounding "".
I am working on Windows 7 64-bit.
One approach is to nest a for %I loop within the forfiles and use the %~I expansion -- use this code in a Command Prompt window:
forfiles /P "C:\root" /M "*.txt" /C "cmd /Q /C for %I in (#relpath) do echo %~I"
To use that code within a batch file you must double the %-signs:
forfiles /P "C:\root" /M "*.txt" /C "cmd /Q /C for %%I in (#relpath) do echo %%~I"
The returned list of files will be (relying on the sample files from the original question):
.\file1.txt
.\file2.txt
Another variant is to nest another forfiles in the body of the initial one, because forfiles removes (non-escaped) double-quotes within given strings like the command line after /C:
forfiles /P "C:\root" /M "*.txt" /C "cmd /C forfiles /P #path\.. /M #file /C \"cmd /C echo #relpath\""
Or alternatively (the doubled inner forfiles is intentional, this works around a bug -- see this post):
forfiles /P "C:\root" /M "*.txt" /C "forfiles forfiles /P #path\.. /M #file /C \"cmd /C echo #relpath\""
The inner forfiles will enumerate exactly one item, which is the one passed over by the outer loop. Since #relpath is already expanded when the inner loop is executed, the quotes are removed as they are not escaped.
So the returned list of files looks like (again taking the sample files from the original question):
.\file1.txt
.\file2.txt
The additional line-break between the lines is generated by forfiles. You can avoid that using redirection (dismiss forfiles output, but display only the echo output in the console window):
> nul forfiles /P "C:\root" /M "*.txt" /C "cmd /C forfiles /P #path\.. /M #file /C 0x22cmd /C > con echo #relpath0x22"
I remove the quotes like this:
#ECHO OFF
GOTO START
usage:
script.bat "*.txt" "c:\Documents"
script.bat "*.txt"
script.bat
If no arguments added it will crawl the current directory with wildcard mask (*)
Avoid root directory (c:\) because too many sub directories for the output console.
:START
IF "%~2"=="" (SET "_FD=%CD%") ELSE (SET "_FD=%~2")
IF "%~1"=="" (SET "_MA=*") ELSE (SET "_MA=%~1")
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "usebackq delims=" %%A in (
`forfiles /p %_FD% /s /m %_MA% /C "cmd /c ECHO #relpath"`
) DO (
SET "myfile=%%~A"
ECHO !myfile:~2!
)
ENDLOCAL
GOTO :EOF
results:
thumbnails\A0-1.jpg
thumbnails\new folder\img.jpg
I'm running this in batch file:
forfiles /p "%~dp0" /c "echo #FILE"
and when I run it, I get this error:
C:\Users\Zach\Desktop\New folder>forfiles /p "C:\Users\Zach\Desktop\New folder\" /c "echo #FILE"
ERROR: Invalid argument/option - '#FILE'.
Type "FORFILES /?" for usage.
What's the problem with #FILE?
%~dp0 includes a tailing backslash. And this is what is causing your problems (this and what monacraft points)
So, change your code to
forfiles /p "%~dp0." /c "cmd /c echo #FILE"
Two things:
Use cmd /c
forfiles /p "%~dp0" /c "cmd /c echo #FILE"
And why use #echo file in the first place?
forfiles /p "%~dp0"
Both should work.
Mona