Use Forfiles To Process Files Based On Age
It is always good to know some command line magic, as it is sometimes easier to process commands that way.
This guide demonstrates the Forfiles command in Windows Vista and Windows 7 (Update: Also available in newer versions of Windows).
Forfiles can process files based on names, file extensions and age. It is for instance possible to find all documents in a directory that are older than 20 days, or all documents in c:\documents that have been changed since a specific date.
The forfiles command can be coupled with processing options to delete those files, or to create a list of all files that match the filters. Lets take a closer look at the forfiles command.
FORFILES [/P pathname] [/M searchmask] [/S] [/C command] [/D [+ | -] {dd/MM/yyyy | dd}]
Description: Selects a file (or set of files) and executes a command on that file. This is helpful for batch jobs.
Parameter List:
- /P pathname Indicates the path to start searching. The default folder is the current working directory (.).
- /M searchmask Searches files according to a searchmask. The default searchmask is '*' .
- /S Instructs forfiles to recurse into subdirectories. Like "DIR /S".
- /C command Indicates the command to execute for each file. Command strings should be wrapped in double quotes. The default command is "cmd /c echo @file".
The following variables can be used in the command string:
- @file - returns the name of the file.
- @fname - returns the file name without extension.
- @ext - returns only the extension of the file.
- @path - returns the full path of the file.
- @relpath - returns the relative path of the file.
- @isdir - returns "TRUE" if a file type is a directory, and "FALSE" for files.
- @fsize - returns the size of the file in bytes.
- @fdate - returns the last modified date of the file.
- @ftime - returns the last modified time of the file.
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".
/D date Selects files with a last modified date greater than or equal to (+), or less than or equal to (-), the specified date using the "dd/MM/yyyy" format; or selects files with a last modified date greater than or equal to (+) the current date plus "dd" days, or less than or equal to (-) the current date minus "dd" days. A valid "dd" number of days can be any number in the range of 0 - 32768. "+" is taken as default sign if not specified.
/? Displays this help message. This help file can be opened by entering the command forfiles /? in a command prompt. Press Windows-R, type cmd, and hit enter to launch the command line in Windows.
The command forfiles /P c:\test\ /M .doc /S /D -10
searches the directory c:\test and all its subdirectories for files with the .doc extension that are older than 10 days.
The parameter /p followed by a directory defines the starting directory, /s includes subdirectories in the search, /m filters the files and folders based on the entered string, and /D defines the date or a time span.
The /C command is used to process the files that are found further. It can for instance be used to run the following command: /C "cmd /c echo @fname" > test.txt
echo the names of each file found and save the results in text.txt in the same directory.
The full command then looks like this forfiles /P c:\test\ /M .doc /S /D -10 /C "cmd /c echo @fname" > test.txt
Another possibility is to delete the files that match the search, this is done with the command /C "cmd /c del @File
It is however recommended to test the output first, before issuing the delete command to make sure that only the right files are deleted. Experienced users may create a batch file to execute forfiles regularly.
@Bernard: Guess not, I have tried more or less the same without success. Tried piping it out like this:
forfiles…. | set var=@file
didn’t work for me, don’t know why. If u find out, share please :-)
Is there a way to save the output of forfiles in a variable?
I tried things like /C set var=@file or /c “cmd /c set var=@file” but without success.
Thanks,
Wow, thanks for this article Martin, just what I needed. Been looking for ways to selectively zero out old videos downloaded by Miro without actually deleting the files completely since Miro has a limited history memory. I think this combined with the output into file echo “0” > file.mp4 will work like a charm. Coool :-)
You are welcome Tobey ;)
Yes, nice tip, I’ve been using this on my server to keep the back-log of certain folders down to a number of days worth. My script, delold.cmd, is:
forfiles -p %1 -m %2 -d -%3 -c “%comspec% /C del @FILE” %4
verify >nul
I think the verify command is to stop the batch file returning odd errorlevels to whatever calls it, so
delold.cmd D:\MySQL\Dumps *.* 30
clears out MySQL dumps older than 30 days
delold.cmd C:\inetpub\logs\LogFiles *.log 60 -s
clears out IIS logs older than 60 and includes subfolders
Martin,
Thanks for the helpful information.