I want to delete *.sql files older than 90 days using batch file and I wrote following command.
forfiles /M *.sql /d -90 /c "cmd /c del #file
I am not sure above command is valid? and if not need suggestions.
forfiles /M *.sql /d -90 /c "cmd /c del #file
SYNTAX (FOR WIN XP FORFILES RESOURCE KIT)
FORFILES [-p Path] [-m Mask] [-s] [-c Command] [-d [+ | -] {dd/MM/yyyy | dd}]
You haven't specified a path, so it will default to your current directory. Also, you didn't close out the quotes at the end of your command. For the sake of safety, I would specify your path.
forfiles -p"C:\Path\To\sqlfiles" -m *.sql -d-90 -c"cmd /c del #FILE"
For your example, not specifying a path:
forfiles -m *.sql -d-90 /c"cmd /c del #FILE"
EDIT: Edited my command as using / instead of - for the switch symbols doesn't work. Removed the link as well because it stated otherwise. Please note: do not insert spaces between the switch and inputs as it will fail. Also, your # parameter must be in all caps. Also to note, the online documentation on ss64.com is incorrect for the usage of #PATH
Related
I'm trying to move hl7 files older then 7 days. My script is
forfiles /p C:\TEST /m *.hl7* /s /d -30 /c "cmd /c move #file C:\New Folder"
pause
I'm getting error like
The syntax of the command is incorrect.
The syntax of the command is incorrect.
The syntax of the command is incorrect.
The syntax of the command is incorrect.
The syntax of the command is incorrect.
The syntax of the command is incorrect.
The syntax of the command is incorrect.
Any help? please.
This is because New Folder has a space in it and forfiles doesn't know how to handle that.
Normally, you'd put paths with spaces in quotes to tell cmd that everything inside of the quotes should be considered a single item. Unfortunately, the entire "cmd /c move #file C:\New Folder" is already in quotes, so adding more quotes inside of those quotes is only going to make things worse. The good news is that in forfiles /?, there's a line that reads
To include special characters in the command line, use the hexadecimal code for the character in 0xHH format (ex. 0x09 for tab). Internal CMD.exe commands should be preceded with "cmd /c".
The hexadecimal version of " is 0x22, and if you change your command to forfiles /p C:\TEST /m *.hl7 /s /d -7 /c "cmd /c move #file 0x22C:\New Folder0x22", then your script will work correctly.
Assuming you must use a Windows batch file, (not powershell), and one wants to delete all files ending in .zip that are in the current active directory. How to do this?
All attempts so far are failing:
forfiles -p "C:\temp\test" -s -m *.zip -d 1 -c "cmd /c del *.zip"
For this it says
ERROR: No files found with the specified search criteria.
As suggested in my comment, your problem could easily be solved by reading the usage information for your command, (available when entering FORFILES /? at the Command Prompt).
Based on your questions criteria, "delete all files ending in .zip that are in the current active directory":
You don't need to use the /P option because as stated in the usage information, "The default folder is the current working directory (.)".
There is nothing in your question regarding recursing subdirectories of the current directory, so the /S option which "Instructs forfiles to recurse into subdirectories" is not required.
For the /D option you are looking for files with a last modified date less than yesterday, i.e. "the current date minus "dd" days", /D -1.
Because you're wanting to delete files in the current directory, there's no need to use the "Full path of the file", #path, so what you need is the "The name of the file", #file.
FORFILES /M *.zip /D -1 /C "CMD /C DEL #file"
You did not mention anything about subdirectories or windows version so I'm assuming somewhat. You have an old version syntax. In Windows 7 and further the syntax changed a little bit.
For windows 7:
forfiles /P "C:\temp\test" /S /M *.zip /D -1 /C "cmd /c del #path"
Using the forfiles batch command, sometimes the #path variable and the #file variable are the same, and sometimes they are different. This looks like a bug to me.
To illustrate - setup:
md test_subfolder
echo Hello>test_subfolder\test.txt
Now #path and #file are different, like you would expect:
forfiles /p test_subfolder /c "cmd /c echo CD: [%cd%] PATH: [#path] FILE: [#file]"
That yields:
CD: [D:\] PATH: ["D:\test_subfolder\test.txt"] FILE: ["test.txt"]
Now, try overwriting the file using #path. This does what you would expect.
forfiles /p test_subfolder /c "cmd /c echo Goodbye>#path"
type test_subfolder\test.txt
Result:
Goodbye
Trying the same thing using #file instead of #path:
forfiles /p test_subfolder /c "cmd /c echo Farewell>#file"
This should create a new file in the root, and leave the file in the subfolder unchanged. But instead, it behaves the same way that the #path does.
Checking for the file in the root folder:
dir test.txt
Result:
Volume in drive D is Recovery
Volume Serial Number is AE9D-4134
Directory of D:\
File Not Found
Looking in the subfolder:
type test_subfolder\test.txt
Result:
Farewell
This is using Windows 7 Professional - I don't know how it might work in other versions.
How can I get #file to behave the way I expect?
This is not a bug. The real problem is the point where the parser expands %CD%, it is done immediately, so you see the current directory of the cmd instance you are working in.
The cmd instance opened by forfiles receives the path provided at /p as the current directory. To see this, change the command line to:
forfiles /p test_subfolder /c "cmd /c echo CD: [0x25cd0x25] PATH: [#path] FILE: [#file]"
0x25 represents the hex. code of the % sign, so expansion of %cd% is not done immediately, but transferred to the "inner" cmd instance.
This will show you that the echo command is actually executed in D:\test_subfolder and so the #file variable expansion of forfiles behaves correctly. Hence the output will be:
CD: [D:\test_subfolder] PATH: ["D:\test_subfolder\test.txt"] FILE: ["test.txt"]
This explains why your line of code forfiles /p test_subfolder /c "cmd /c echo Farewell>#file", when executed in D:\, (over-)writes the file D:\test_subfolder\test.txt rather than creating a new file D:\test.txt.
Hm ... this works! It's a mystery to me why, though.
forfiles /p test_subfolder /c "cmd /c echo So Long>%CD%#file"
type test.txt
Result:
So Long
forfiles /p test_subfolder /c "cmd /c echo So Long>%CD%\#file" command is working for me,[please note that i have used "\" after %CD%] , you need write to a file in the sub directory , you are trying to execute the above command outside the sub folder , probabaly that might me the reason you are feeling the difference between #path and #file
I have a batch script that I have run through Task Scheduler every night at midnight. Here is the script:
forfiles /M *.bak /p "Z:\Logs" /S /D -5 /C "cmd /c del #file : date >= 5 days >NUL"
But when the task runs at midnight, it does not delete the files older than 5 days. If I double click on the batch file and run it manually, it does delete the files older than 5 days. What is wrong or do I need to do something different to make this work?
EDIT:
Here is my full batch file and more information about the task schedule:
sqlcmd -S server\SQLEXPRESS -U user -P password -i "D:\BackupPrograms\translogsbackup.sql"
forfiles /M *.trn /p "Z:\Logs" /S /D -5 /C "cmd /c del #file >NUL"
I am using an administrator account for the task schedule to run every night. I am trying to get it to delete the older backups that the sqlcmd is creating, that way I make sure I am not wasting a bunch of space on Full SQL backups that are not needed. I hope this helps more. I am just confused why the batch file would act differently running through the Task Scheduler and when I double click on it to run.
It doesn't work from the command prompt any more than it does from the scheduler, and here's why.
/C "cmd /c del #file : date >= 5 days>NUL"
The : is illegal at that position in a command line, and it's ignored.
The >= is interpreted as the output redirection symbol, and therefore all of the output is redirected to a file named 5 in the current directory.
You can test this at a command prompt yourself:
Create a new, empty folder on your system, such as C:\Test, from a command prompt, and make it the active directory.
C:\>md Test
C:\>cd Test
Create a couple of dummy files in the folder:
C:\Test>echo file1 > file1.txt
C:\Test>
C:\Test>echo file2 > file2.txt
Do a directory to see what's there:
C:\Test>dir /b
file1.txt
file2.txt
C:\Test>
Try this forfiles command to see the output:
C:\Test>forfiles /M *.txt /C "cmd /c echo #file"
"file1.txt"
"file2.txt"
C:\Test>
Change the forfiles to add the : date >= 5 days and run again:
C:\Test>forfiles /M *.txt /C "cmd /c echo #file : date >= 5 days"
C:\Test>
Do a directory to see what's there:
C:\Test>dir /b
5
file1.txt
file2.txt
C:\Test>
Note the new file with the name 5.
So the solution: Delete the : date >= 5 days. You can leave the NUL portion, as that legitimately redirects any output to NUL (nothing) so that it's not displayed. So your command would look like this:
forfiles /M *.bak /p "Z:\Logs" /S /D -5 /C "cmd /c del #file >NUL"
I cant get FORFILES to work for me. I run a .bat that backs up a few databases I have each day using this one example below.
COPY "X:\W Attendenance\C Crew Attendance\Attendance Control DB v4.xx.accdb" "X:\Supervisors Log\Backups\Attendance Bak\bak_%currdate%_Attendance Control DB v4.xx.accdb"
Then after running my backups I wanted to delete the old files that were older than five days by using the below example.
FORFILES /p "X:\Supervisors Log\Backups\Attendance Bak\" /d -5 /c "cmd /c del #path "
But what happens is it creates the backups but never deletes the old ones. What am I doing wrong?
Ken it still seems to not work. I changed the #file to #path and ran and I still have my backups. I also had another question, can I limit the delete to just files starting in bak_ ? and can I delete the file by its name because every backup starts with bak_ then the date mm-dd-yyyy_ then name of the file...
This fixed it... Thanks for your help and links!
forfiles -p "X:\Supervisors Log\Backups\Attendance Bak" -s -m *.* -d -1 -c "cmd /c del #path"
On a side note that only is able to delete the File but Sometimes I needed to delete a folder and everything in it so I use:
FORFILES /P "H:\BACKUPS\bk_Operator_Rate_Program" /d -10 /c "cmd /c IF #isdir == TRUE rd /S /Q #path"