mmv: mass rename of files (and more!)
Under good old DOS you could rename multiple files by saying
REN A*.* B*.*
to change every leading A to B. Using mv from unix-like systems, this won't work. You could write a loop in your preferred shell, but this is too much to type, error-prone and generally uncool. But fear not: mmv to the rescue! Changing leading As to Bs is as simple as this:
mmv A\* B\#1
What does this do?
The first parameter is the search pattern. mmv looks for any filenames starting with A followed by anything else. The asterisk is a wildcard and just as in most shells, it matches one or more arbitrary characters (You can also use a question mark to match just a single character). Note that you should escape asterisks and question marks to prevent your shell from expanding them.
The second parameter is the target filename. Every wildcard that matched in the search pattern can be inserted here by writing a hash sign followed a number. The number is that of the wildcard, counting from the left: the first wildcard becomes #1, second #2 and so on. We have just one wildcard (the asterisk), so we write a #1. Everything that matched the asterisk (all characters after the A in the initial filename) will be put after the B in the new filename. This effectively changes the leading A to B.
Note that the hash sign should be escaped as well.
Examples
Let's see what mmv actually does with two example files. Let's create a fresh folder with two neat and clean empty files:
$ mkdir /tmp/mmv $ cd /tmp/mmv $ touch Aone Atwo
Now we run mmv. The option -n tells it to just print what it would do instead of renaming any files, because we want to use these our freshly created files in multiple examples:
$ mmv -n A\* B\#1 Aone -> Bone Atwo -> Btwo
Just as expected, this would change the first letter of our files. Now let's move the replacement mark to the front:
$ mmv -n A\* \#1B Aone -> oneB Atwo -> twoB
The filenames that began with A would now end with B. We can also use the replacement multiple times:
$ mmv -n A\* \#1B\#1 Aone -> oneBone Atwo -> twoBtwo
It's that easy. But renaming files from A to B is a bit boring. Here is a real-life example: Say that the photos from your digital camera always end up with .JPG instead of .jpg. mmv will rename them for you in one go. It's like above, but this time we tell it to change "everything ending with .JPG" to "first matched string plus .jpg":
mmv \*.JPG \#1.jpg
Escaping can be done using the backslash or by putting your strings inside some quotes. This comes especially handy when you have multiple search and replacement patterns. These are some more examples that should speak for themselves. Note the reversed order of the replacements in the last example:
# back up logfiles $ mmv \*.log \#1.log.old # remove two zeroes. note that every ? counts as one match $ mmv 'img00???.jpg' 'image_#1#2#3.jpg' # change date format between YYYY.MM.DD and DD.MM.YYYY $ mmv "data-*.*.*.log" "data-#3.#2.#1.log"
Details
What happens when you forget to escape your wildcards? Well, in most cases, your shell will expand the wildcards to more than two filenames and mmv will complain about the wrong number of arguments. If it expands to just two filenames, the rename should happen as requested. No harm done. You might get into trouble when you have files that look like command line parameters - but this is always a bad idea. Think of a "rm *" that runs into a file called "-rf".
mmv will also complain when it is about to overwrite an already existing file. You can choose to keep or overwrite your old file:
$ touch Bone $ mmv -n A\* B\#1 Aone -> Bone : delete old Bone?
Above I said that writing a shell loop is error prone. What if you made a mistake and some of your target files will get the same name? The last one survives. This is no problem for mmv: it warns you when the resulting filenames are not unique:
$ mmv -n A\* all-the-same Aone , Atwo -> all-the-same : collision. Nothing done.
Some other features of mmv are:
- it allows you to change strings to upper or lower case in the target name (use #u1 or #l1 instead of just #1).
- if you want to rename directories, you have to use the -r option.
- even circular renames (naming A to B and B to A simuntaneously) are done properly
mmv is not limited to just renaming files, it is also able to copy or append files or create links to files. This can either be achieved by using the corresponding option to mmv or by calling the mcp, mad and mln commands. For details on this or even more, please see the manpage mmv(1).
Alternatives
Tools similar to mmv are vidir and rename. They have some differences, though:
vidir, which is part of the moreutils package (which has already been featured on DPotD), opens all filenames in a selected directory in your favourite $EDITOR, one filename per line. You can then simply edit the filenames and vidir renames them after leaving your editor. You can use all the power of your editor, eg. search and replace or macros.
rename is part of the perl package (it's an alternative linking to /usr/bin/prename, so there are probably other packages that provide it, too). It gives you the power of Perl and expects one Perl regular expression for renaming the files. Using the /e modifier gives you maximum flexibility: Ever thought about squaring a number that is contained in your filenames?
$ for I in $(seq 4); do touch file_$I.empty; done $ rename -n -v 's/file_(\d+)/"squared_".$1*$1/e' file_* file_1.empty renamed as squared_1.empty file_2.empty renamed as squared_4.empty file_3.empty renamed as squared_9.empty file_4.empty renamed as squared_16.empty
While rename warns about files being overwritten, unlike mmv this is not checked for all files at the beginning. So you might be left with 50 files renamed and 50 files not renamed when the error occurs halfway through your file list.
Conclusion
For me, from the above three mmv is the best tool for everyday use as it has the easiest syntax, is enough for most of my daily needs and is more robust when it hits duplicate filenames. vidir is great for renames that follow no strict pattern and have to be done at least partly manually while rename with the /e modifier can tackle even the weirdest cases of mass file renames.
Packages and links
mmv has no homepage, according to Debian's copyright file the package has been put together from sources obtained from USENET. mmv has been around for a long time, it's available since at least Woody in Debian and Warty in Ubuntu.
- Debian Stable Package: http://packages.debian.org/stable/utils/mmv
- Ubuntu Feisty Package: http://packages.ubuntu.com/feisty/utils/mmv
It does not seem to be included in current Knoppix DVDs though, because one day Bernhard came to me screaming in horror "There is no mmv in Debian!" and I told him "Well, it's propably just not in your Knoppix" and to prove my point I wrote this entry for DPoD :-)
Michal Šustr am : Michal Šustr via Twitter