#ECHO OFF
SET backdir=backup
SET snapshotdir=snapshots
SET worldprefix=world_
SET itdate=%date:~10,4%-%date:~4,2%-%date:~7,2%
SET hour=%time:~0,2%
IF "%hour:~0,1%" == " " SET hour=0%hour:~1,1%
echo Current date: %itdate%. Current hour: %hour%. Current Minute:Second: %time:~3,2%:%time:~6,2%
forfiles /m "%worldprefix%*" /c (
echo Copying World: #path
cmd /c xcopy /e /c /h /i /v /r /y /q #file %snapshotdir%\#file\%itdate%-%hour%-%time:~3,2%-%time:~6,2%
cmd /c xcopy /e /c /h /i /v /r /y /q #file %backdir%\%itdate%D\worlds\#file
)
echo Copying Plugins
xcopy /e /c /h /i /v /r /y /q plugins %backdir%\%itdate%D\plugins\
xcopy /e /c /h /i /v /r /y /q %backdir%\%itdate%D %backdir%\%itdate%-%hour%H\
echo Backup Complete (assuming no errors above). Attempting to remove old files..
forfiles /p "%snapshotdir%" /c "cmd /c rmdir /s /q #path" /d -7
forfiles /p "%backdir%" /m "*H" /c "cmd /c rmdir /s /q #path" /d -2
forfiles /p "%backdir%" /m "*D" /c "cmd /c rmdir /s /q #path" /d -14
PAUSE
I am trying to copy all files with "world_" as a prefix. I run into a problem when I try to use multiple commands in a loop. I have attempted to write the batch script I want above.
The two commands have absolutely nothing in common, so no, you cannot use parentheses like that.
You must execute all the commands within a single CMD /C. You can concatenate commands on one line using &. I've defined a simple XCOPY "macro" to save a bit of typing.
set XCOPY=xcopy /e /c /h /i /v /r /y /q"
forfiles /m "%worldprefix%*" /c "cmd /c echo Copying World: #path&%XCOPY% #file %snapshotdir%\#file\%itdate%-%hour%-%time:~3,2%-%time:~6,2%&%XCOPY% #file %backdir%\%itdate%D\worlds\#file"
If you escape the quotes, then you can use line continuation to split the logical line accross multiple lines. But then you must also escape the &.
set XCOPY=xcopy /e /c /h /i /v /r /y /q"
forfiles /m "%worldprefix%*" /c ^"cmd /c ^
echo Copying World: #path ^&^
%XCOPY% #file %snapshotdir%\#file\%itdate%-%hour%-%time:~3,2%-%time:~6,2% ^&^
%XCOPY% #file %backdir%\%itdate%D\worlds\#file^"
Or you could put the & in the front of the line so that you don't need to escape it. The line continuation also escapes the first character of the next line:
set XCOPY=xcopy /e /c /h /i /v /r /y /q"
forfiles /m "%worldprefix%*" /c ^"cmd /c ^
echo Copying World: #path^
&%XCOPY% #file %snapshotdir%\#file\%itdate%-%hour%-%time:~3,2%-%time:~6,2%^
&%XCOPY% #file %backdir%\%itdate%D\worlds\#file^"
I realize this is an old post, but another way of doing it is to call a batch file and pass it the parameters that it needs. And I do not believe that there is any limitations in what can be in that batch file. For example:
forfiles /M "*.img" /C "cmd /c ProcessFile.bat #file #fdate #ftime"
Related
I have created a batch script to delete 7 days older files as follows:
ForFiles /p "C:\Users\John.Kapen\Desktop" /s /d -7 /c "cmd /c del #file"
But this is deleting executable files and folders as well.
I tried below command to exclude executable file deletion. But not working:
for /f %%F in ('C:\Users\John.Kapen\Desktop /b /d -7 /a-d ^| findstr /vile ".exe"') do del "%%F"
Could someone help me here?
The forfiles /? "manpage" contains following information:
...
#ext - returns only the extension of the
file.
...
Examples:
...
FORFILES /M *.txt /C "cmd /c if #isdir==FALSE notepad.exe #file"
You can try something like (not tested):
ForFiles /p "C:\Users\John.Kapen\Desktop" /s /d -7 /c "cmd /c if NOT #ext=="""exe""" del #file"
F.e. there is some folder on user's desktop. I want to remove any files within this folder except shortcuts. There are two types of shortcuts - to some local\network resources and shortcuts to some sites.
"shortcuts on some local\network resources" have .lnk extension
"shortcuts to some sites" have .url extension
I've already found how to do this task separately
forfiles /p "%userprofile%\Desktop\folder" /s /m *.* /c "cmd /c for %G in (#path) do #if /I [%~xG] neq [.lnk] del /F /Q %G"
and
forfiles /p "%userprofile%\Desktop\folder" /s /m *.* /c "cmd /c for %G in (#path) do #if /I [%~xG] neq [.url] del /F /Q %G"
But how to combine these conditions into one string? Something like if /I [%~xG] neq [.lnk] AND [.lnk] ...
There's absolutely no need to use a for-loop within your forfiles /C command.
Try either;
ForFiles /P "%UserProfile%\Desktop\folder" /S /C "Cmd /C If /I Not #ext==\"lnk\" If /I Not #ext==\"url\" Del /A /F #path"
Or use the hex codes as shown in the help information, available at the Command Prompt by entering, forfiles /?
ForFiles /P "%UserProfile%\Desktop\folder" /S /C "Cmd /C If /I Not #ext==0x22lnk0x22 If /I Not #ext==0x22url0x22" Del /A /F #path"
Is there away to only display files in a folder called "Export", when such a subfolder is in multiple locations?
This will display all .xlsx files below where I'm running the batch file from, however I don't want to display all, I only want to display things in a folder called "Export":
forfiles -p "%~dp0\" -s -m *.xlsx -d -365 -c "cmd /c ECHO #relpath"
I have attempted things like:
forfiles -p "%~dp0\*\Export" -s -m *.xlsx -d -365 -c "cmd /c ECHO #relpath"
However it doesn't recognise syntax like this. Says invalid argument/option, but they are valid until I add *\ to the path.
This is an example of the structure I'm working with and what I what results to display:
%~dp0\1\Exports\Excel\ - (Do display .xlsx files)
%~dp0\1\Do Not Delete\Excel\ - (Don't display .xlsx files)
%~dp0\2\Exports\Excel\ - (Do display .xlsx files)
%~dp0\2\Do Not Delete\Excel\ - (Don't display .xlsx files)
The number folders would be a variable somehow, which is why the *\ is in my attempt.
I will then edit this to delete the files when I know it's picking up the right ones.
You could use two nested forfiles loops:
forfiles /S /P "%~dp0\" /M "Export*" /C "cmd /C if #isdir==TRUE forfiles /P #path\Excel /M *.xlsx /D -365 /C 0x22cmd /C echo 00x7840path0x22"
This command line walks through the given root directory (%~dp0) recursively and iterates through all items matching Export* (you might replace this pattern by Export or Exports, depending on your needs); the hierarchy depth is not checked in order to avoid the need of three nested loops. Anyway, if the iterated item is a directory, the sub-directory Excel is enumerated and searched for items matching *.xlsx.
Supplement:
The above command line may display many error messages like ERROR: The specified directory does not exist. or ERROR: Files of type "*.xlsx" not found., depending on your data; to avoid them, redirect STDERR to the nul device:
2> nul forfiles /S /P "%~dp0\" /M "Export*" /C "cmd /C if #isdir==TRUE forfiles /P #path\Excel /M *.xlsx /D -365 /C 0x22cmd /C echo 00x7840path0x22"
The forfiles command returns an empty line to STDOUT, so the above command line will contain many of them; to avoid such too, redirect STDERR and STDOUT to the nul device and redirect only the wished data to the console con:
1> nul 2>&1 forfiles /S /P "%~dp0\" /M "Export*" /C "cmd /C if #isdir==TRUE forfiles /P #path\Excel /M *.xlsx /D -365 /C 0x22cmd /C 1> con echo 00x7840path0x22"
You can send results with | to FINDSTR like this:
FORFILES /P . /S /M *.xlsx /D -365 /C "CMD /C ECHO #path" | ^
FINDSTR "\\Exports\\" | ^
FINDSTR /I /C:Delete /V
So you search every xlsx files located in a certain path (here is current dir) Every xlsx must contain Exports as folder and show every xlsx that doesn't (/V Displays only the non-matching lines) contain "delete" (/I mean insensitive)
In a batch file you can replace /P . by any variable path /P "%~dp0" /P "%CD%" or send as argument /P %1
Also you can do FOR loop to make any command for every match.
In one line to put in console:
FOR /F "usebackq delims=" %A in (`forfiles /p . /s /m *.xlsx /D -365 /C "cmd /c ECHO #path" ^|FINDSTR "\\Exports\\" ^|FINDSTR /I /C:Delete /V`) DO #ECHO FAKE-COMMAND %A
In a batch file:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "usebackq delims=" %%A in (
`forfiles /p . /s /m *.xlsx /D -365 /C "cmd /c ECHO #path" ^|FINDSTR "\\Exports\\" ^|FINDSTR /I /C:Delete /V`
) DO (
SET "myfile=%%~A"
#ECHO FAKE-COMMAND "!myfile!"
)
ENDLOCAL
GOTO :EOF
I am using forfiles to delete files older than 7 days from a specific directory using the following script found elsewhere on this forum:
forfiles -p "H:\E-drev" -m *.* /D -7 /C "cmd /c del #path"
This Works fine except I have some files with no extension eg. a file named TA07l. This file is not deleted. I have tried using #fname instead of #path but this does not help.
Any advice would be greatly appreciated.
The following should work:
forfiles /P "H:\E-drev" /M * /D -7 /C "cmd /C if #isdir==FALSE if #ext==\"\" del #path"
You have to use * instead of *.* because otherwise it will search every files that contain a dot .
Update with few examples between * and *. and *.*:
copy nul _onefilewithoutext
copy nul _onefilewith.ext
mkdir _oneFolder
dir /b /a-d *.
_onefilewithoutext
Forfiles command
forfiles /M *. /C "cmd /C echo #relpath"
Error: File Type "*." not found.
forfiles /M * /C "cmd /C echo #relpath"
".\_onefilewith.ext"
".\_onefilewithoutext"
".\_oneFolder"
forfiles /M *.* /C "cmd /C echo #relpath"
".\_onefilewith.ext"
forfiles /M * /C "cmd /C if #isdir==FALSE echo #relpath"
".\_onefilewith.ext"
".\_onefilewithoutext"
forfiles /M * /C "cmd /C if #isdir==FALSE if #ext==\"\" echo #relpath"
".\_onefilewithoutext"
Can anyone explain me how to do this?
Problem is #fname contains quotes so concatting %source% and #fname gives an error...
forfiles /P "%source%" /M %file%.* /D -1 /C "cmd /c if exists %source%\#fname.pdf del #path"
The double quotes are not the issue. You've got a syntax error in your command line: instead of if exists … it should go if exist ….
For anyone interested this is the full script.
#echo off
set ERRORLEVEL=0
::variables
set source=C:\ASWFORM\argus
set ps2pdf=C:\Progra~1\gs\gs9.07\gs\lib\ps2pdf
::parameters
if [%1]==[] goto hell
if [%2]==[] goto hell
set file=%1
set hotfolder=%2
:: *********************************************************************************************
::delete files from yesterday
forfiles /P "%source%" /M %file%.* /D -1 /C "cmd /c if exist %source%\#fname.pdf del #path"
::create pdf files
forfiles /P "%source%" /M %file%.ps /C "cmd /c call %ps2pdf% #path"
::move files to hotfolder
xcopy /Y /V %source%\%file%.pdf %hotfolder%
xcopy /Y /V %source%\%file%.xml %hotfolder%
xcopy /Y /V %source%\%file%.adj %hotfolder%
forfiles /P "%source%" /M %file%.* /C "cmd /c if exist %source%\#fname.pdf del #fname.ps"
goto heaven
:hell
echo Usage argus.bat [filename without extension] [path to archive hotfolder]
:heaven
exit 0
:: *********************************************************************************************