Sometimes you want to rename a bunch of files. For example, maybe you want to
rename all the .htm files in the directory to .html. Previously I’d give a
shell command like this:
for f in *.htm; do
mv $f $(basename $f .htm).html
done
It works, but it’s cumbersome. There are better tools available. For example,
Perl comes with rename, which lets you do this:
rename 's/\.htm$/.html/' *.htm
Another tool, and the one I’ve been using lately, is zmv, which is a part of
Zsh. The .htm renaming goes like this:
zmv '(*).htm' '$1.html'
As a more advanced example, recently I wanted to rename all the subdirectories
of a directory to uppercase. This was inside a git repo, so I needed to use
git mv instead of plain mv. Here’s how I did it:
zmv -Q -i -p 'git' -o 'mv' '(*)(/)' '${(U)1}'
-Qturns on bare glob qualifiers. This is required for(/), which makes*match only directories.-ienables interactive mode, as I wanted to manually confirm each renaming.-pspecfifies the program and-othe arguments for it.
To use zmv, you need to load it with autoload -U zmv. See man zshcontrib for documentation. I also highly recommend skimming the
Zsh manual on expansion (man zshexpn) – it’s a treasure trove
that keeps giving.