How to perform more complicated search and replace-style renaming in a batch file

Raymond Chen

Last time, we looked at how copying and renaming with wildcards worked in MS-DOS, and how it doesn’t work well if you are trying to perform search-and-replace operations where the strings have different lengths.

For example, if you have a list of files, say fred001.txt through fred999.txt and you want to rename them to wilma001.txt through wilma999.txt, the obvious command

ren fred*.txt wilma*.txt

will not produce the desired results because the a in wilma overwrites the first character that was matched by the wildcard in the source pattern, since fred is only four characters long.

You can still get what you want; you just won’t be able to use the wildcard algorithm to do it.

setlocal enabledelayedexpansion
for %%i in (fred*.txt) do set "_=%%i" & ren "%%i" "!_:fred=wilma!"

We write a little batch file to perform the bulk rename operation.

The main loop is driven by the FOR command, which we ask to enumerate all the files that match the pattern fred*.txt. For each such file, we set the variable _ to the file name. I like to use _ as a scratch variable name in batch files because it’s unlikely to collide with a name that means something to any particular program.¹

We then perform a non-wildcard ren command. The source file name is the file name which the FOR command gave us. The destination file name is the result of a search-replace operation with the _ variable, where we ask to search for fred and change it to wilma.

This is a two-liner instead of a one-liner because we need to enable delayed expansion so that we can delay the search-replace operation until after the _ variable is set.

If I need to do some sort of fancy renaming, I don’t do any of this. I’ll do a dir /b and dump the list of file names into a file. Then I’ll edit that file and use the editor’s fancy search-replace features to convert it into a list of REN commands. I’ll look over the results to verify that they are doing what I want, and possibly perform some editing to deal with special cases like “Don’t rename fred314.txt; that one stays unchanged.” Once I’m satisfied, I save the results as a batch file and run it.

If the editing is particularly complicated, I’ll write a one-off program to generate the batch file. I prefer generating a batch file to having the one-off program perform the renames directly, because that lets me preview the operation. You don’t want to mess it up.

Bonus chatter: The reimagined Windows PowerToys includes an interactive bulk renaming tool called PowerRename.

¹ Sometimes people new to batch programming will have need for a temporary variable to hold a path, and they call it PATH. This tends to result in a lot of head-scratching, since they are unwittingly modifying the executable search path.