Forfiles - My favourite Command Line Tool

Forfiles - My favourite Command Line Tool

Wednesday Aug 01, 2012


Forfiles is my favourite addition to the command line. In my day-to-day, I find myself often needing to iterate through a directory of files. As a programmer, without Forfiles, I'd be looking to power up Visual Studio or PowerShell...overkill.

As it's usually basic functionality I'm looking for a basic solution. Enter, the batch file. I'm the first to say that the Microsof built in command line tools and batch/script language is limited. It's certainly no Unix/Linux shell script but it can do the trick and doesn't need special knowledge like PowerShell.

For instance, I might want to move files from a folder to a printer share. Trouble is, I can't use move to a printer UNC, nor can I just blindly copy all files and then delete all files as new files might be created in the folder while I'm copying, as such the delete *.* will nuke the new files.

Another example is the execution of Ghostscript (or similar) against a folder of files, or worse, a set of directories (subfolders).

Forfiles fills the bill nicely. I typically launch it from one batch file, potentially calling another to process.

In simple terms, you run Forfiles against folder with a given set of filters (date, file name etc.). It acts as a For Loop, allowing you to launch a command and use parts of the filename as variables.

As an aside, you can use it like dir. (dir /b to be more precise).

I DO HAVE ONE FRUSTRATION:

Adding quotes inside the alreadyed quoted cmd /c command doesn't appear to be possible. Some say they have gotten it to work but I haven't been able to. In those cases I create a batch file that accepts input. This works as long as your filename or path doesn't have spaces.

As for the quirk, be aware that this isn't like an array th

Syntax:

Forfiles.exe - returns a list of files in the folder (like dir /b but with quotes and it includes hidden etc.)

To filter the results you can use the following on their own or combined:

  • File filter: /m <filter> - /m *.pdf
  • Last Modified Date Range: /d <+/-><MM/DD/YYYY> 
  • Last Modified Day Range: /d <+|-><days> 
  • Specific Folder: /p <folder> - /p c:\temp
  • Subfolders: /s 

To launch a program/batch:

  • /c "<program to run>"

When launching a program/batch you can use the following variables:

  • @FILE - File name
  • @FNAME - File name, no extension
  • @EXT - File name, just extension
  • @PATH - Full path of the file (inluding filename)
  • @RELPATH - Relative path of the file (including filename)
  • @ISDIR - Returns TRUE/FALSE for evaluation
  • @FSIZE - File size (bytes)
  • @FDATE - Last modified date
  • @FTIME - Last modified time

Examples:

Delete PDF files older than 30 days from c:\processed

forfiles /p c:\processed /m *.pdf /d -30 /c "cmd /c del @PATH"

Delete all files, but not directories, from all subfolders of c:\temp

forfiles /p c:\temp /s /c "cmd /c if @isdir==FALSE del @PATH"

Run batch file against files in the current folder, passing in the filename and extension as varaibles

forfiles /c "cmd /c go.bat @FILE @EXT