Sunday, December 11, 2011

Windows command line survival: findfiles, find+xargs's dim cousin

Sometimes, we have to use the Microsoft Windows cmd.exe command line. Maybe it's at a client site or on a user machine where installing PowerShell, Cygwin or Mingw isn't appropriate. Maybe you're on a domain member so locked down by group policy you can't do anything if you want to. Either way, you have to use cmd.exe, and you're swearing.

I find out about the odd useful command that makes the Windows shell more usable, and I'll be trying to post them here. The first is forfiles, a basic alternative to find -exec or find|xargs.

If you're missing find -exec (or xargs) it turns out that Windows provides forfiles to do a limited subset of the work that find -exec can do. This'll help with simple jobs like flattening out a deep directory tree into a flat folder of files, running a command recursively on every file in a directory, etc.

For example, here's how to find every TrueType font file within the deep directory tree C:\deeptree and copy the files to C:\flat.

forfiles /s /p C:\deeptree /M *.ttf /c "cmd /c move @file C:\flat"

You really want to use an absolute path when you invoke move here, as it's invoked with the file's parent directory as its cwd, not the directory you ran the findfiles command in. Use a relative path and you'll just land up renaming all your files - which is a handy trick, but not what you intended.

In reality you'll also want to use more appropriate paths than folders off the root of C:\ . Beware spaces in pathnames, and remember that Windows has totally different rules to *nix in this area.

This particular case can be just as easily accomplished by doing a search for *.ttf from the parent directory, selecting all, copying, and pasting into an empty directory. More complex uses of this command like recursive renames or command invocations, not so much.

See forfiles /? for help.

No comments:

Post a Comment