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}'
-Q
turns on bare glob qualifiers. This is required for(/)
, which makes*
match only directories.-i
enables interactive mode, as I wanted to manually confirm each renaming.-p
specfifies the program and-o
the 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.