FORFILES, for your fancier batch file enumeration needs

Variations on the
for /f %%i in ('dir /b ...')
will let you repeat an operation on the contents of a directory,
possibly even recursively if you add the /s option,
with some basic attribute-level filtering if you add the
/a or /a- flags.

For your fancy recursive file operations,
there's a tool called
FORFILES which iterates through the contents of a
directory (recursively if requested),
executing a command on each item it finds.
It also has additional filtering capability,
like selecting files based on their last-modified time.
For example,
you could copy all files in the current directory which were
modified today:

forfiles /D +0 /c "cmd /c copy @file \\server\today"

Unfortuantely, the /D option is not as flexible
as one might like.
For example, while it can pick files modified today,
it can't pick files modified in the last week,
because the relative-date-picker knows only how to pick
files modified on or before a date in the past
or
files modified on or after a date in the future.
(Who the heck wants to operate on files modified in the future?
Except perhaps the Microsoft Research folks who are working
on that time machine.)

You can type FORFILES /? for more information on what
you can do (and by seeing what's omitted, what you can't do).

If the command you want to execute is rather long,
you can offload it back into the batch file being executed:

One gotcha here is that since each command runs in a sub-shell,
it can read environment variables, but any modifications it makes
to environment variables will be lost since the command is modifying
only its local environment variables.
A workaround for this is to use FORFILES to select
the data to operate on,
but use FOR to actually perform the operation.
Since FOR runs inside the main command interpreter,
it can modify environment variables.

Nooooooooo!!!! At least, it's only 51 weeks for next years Batch File Week.

I actually enjoyed it: I learned a few tricks that may make my life easier. I wish it had been more variated, instead on focusing so much in fors. But, hey, it's Raymond's blog, and Raymond writes what he wants to.

I too enjoyed Batch File Week and hope to see it again next year (I do much so prefer it to CLR week, fwiw). This has been a great week filled with a ton of useful information (seriously!). Thanks Raymond.

Remove -maxdepth 1 to recurse into subdirectories. The variety of file time tests, along with the -a (AND), -o (OR) and ! (NOT) operators, allow for pretty much any time you can imagine, including finding files modified after a date in the future.

Like any Unix process, find can't modify environment variables in its parent shell. If you really wanted to do that (which by its very nature is not idiomatic), you could produce as output a set of NAME=VALUE mappings and pipe that into the 'source' shell builtin, e.g.:

How come I've never heard of FORFILES before? I actually had to try it out myself because I couldn't believe this comes preinstalled with Windows. Always used PowerShell or a short C# snippet because I find it hard to remember the verbose FOR syntax.

Does anyone know how old "forfiles" is? On the MSDN pages I can't find any mention of the earliest verison of Windows (or DOS?) that it was shipped with. It says "Applies To: Windows Server 2008, Windows Vista", but it says the same thing about "cd", which definitely shipped with earlier versions than that! :-)

FOR (and FOR /R) won't work with hidden files, and I couldn't work out how to get FOR … ('DIR/S/A') to work with Unicode file names (yes I tried CMD /U), so FORFILES turned out to be really useful in that case.

For completeness, as someone pointed out in a previous post's comment, tokens=* doesn't work, you need to use delims= to properly handle file names including spaces.

Thanks for this series! I only read the last one and I learned something already. It's a real pity this command isn't more obviously available. Any idea where I could've learned about it without knowing it exists? I've looked at the output of 'help' in the command line, but it isn't there. Is there something like help advanced or so, with all the advanced stuff in it?

[It's not listed in HELP because the command was added later, and the people who added it didn't ask the CMD folks "Hey, could you add this to HELP?" There are lots of commands not included in the HELP list, like WHERE and PowerShell. -Raymond]