Batch File Renaming
unix zsh


The need to rename multiple files is a common annoyance for anyone who uses a computer. Even if you name files correctly, there are times when it’s critical to be able to batch rename a set of files. The Z-shell provided a convenient way to quickly rename a set of files.

Zsh is a UNIX shell that borrows many of the best features from the Bourne-again and Korn shells. Supplied within the Z-shell is a very useful function called zmv, which can be used to very easily batch rename files with simple one-line commands. zmv essentially works by taking two arguments; a glob pattern to match and a string that uses the match pattern for, in our case, file renaming actions.

Here are a few recipes using zmv for common batch file naming manipulations. Note that depending on your Z-shell configurations you may have to autoload zmv or alter your .zshrc file before the code below will work.

Changing file extensions:

$ zmv -n '(*).txt' '$1.rtf'

The -n argument forces zmv to print the output without actually performing the rename operation. In this way, -n acts as a safety net so we don't screw anything up permanently! To actually perform the file renaming run the command without the -n flag. The '(*).txt' '$1.rtf' code indicates that for any file with the .txt extension that is not hidden, keep the name of the file the same, but change the file extension to .rft.

Changing file extensions recursively:

$ zmv -Q '(**/)(*).txt' '$1$2.rtf'

The -Q flag allows hidden files to be matched along with visible files. Adding the (**/) code will cause zmv to change the file extension on all .txt files in the current directory and any text files in any sub-directories (visible or hidden).

Renaming files serially:

$ c=1 zmv '*.txt' '$((c++)).txt'

Rename all .txt files in the current directory starting with the file name substitution, 1.txt and increment from 1 to ∞. c=1 specifies the starting name substitution. Note that any file which has the exact name as an attempted substitution will throw an error. For example, if a directory already contains a file called 1.txt, this command will not work.

Renaming files selectively:

$ zmv '(*).txt' '${1//foo/bar}.txt'

For any file in the current directory that contains the string foo in the file name, replace all instances of foo with bar. zmv supports extensive regex matching, so if you need it, the file renaming parameters can become extremely sophisticated.

These recipes are just a few simple and common examples of how zmv can be used for batch file renaming actions. If you use a precise file naming method, zmv is a phenomenal function for quickly updating/changing your file names.