Batch renaming
Contents |
Most systems have a version of rename for renaming multiple files in one go. This command is incredibly useful. I'll talk about two different versions of this command that you might find on your system.
util-linux(-ng) rename
The simplest incarnation is the one in util-linux (or util-linux-ng), which replaces the first occurrence of a string in a filename with another string. This comes standard in most distros, including Redhat-related ones like CentOS and Fedora.
This simple utility takes three arguments: it replaces the first occurrence of the first argument with the second argument. The third argument is the list of files to rename.
Say you have a bunch of files like file1.txt, file2.txt, ... file9.txt. Now you create a file10.txt, but in your file manager, file10 gets sorted between file1 and file2 instead of after file9. To fix this, append "0" to "file" in every filename that has only one digit:
$ rename file file0 file?.txt
Now you have file01.txt, ... file09.txt, file10.txt.
Undoing what you just did is equally simple:
$ rename file0 file file0?.txt
Or just:
$ rename 0 '' file0?.txt
This simple rename utility can even add prefixes. If you have a directory with files like "Sandstorm.mp3" and "Calm Before the Storm.mp3" and you want to prepend "Darude - " to each of them, you can do:
$ rename '' 'Darude - ' *.mp3
To do the reverse (remove the prefix):
$ rename 'Darude - ' '' 'Darude - '*.mp3
Easy, right?
prename
The renaming utility that comes by default with Ubuntu is a Perl program sometimes called prename. It uses Perl regular expressions rather than simple match-and-replace, so it is a far more powerful utility. However, it might be a little harder to use at first because of the requirement that you have at least a basic understanding of regular expressions. Regular-expressions.info is an excellent resource of information about regular expressions, and I highly recommend it.
This program can do everything the simpler one can do, plus more. For example, to rename file1.txt, file2.txt, ... file9.txt, file10.txt to file01.txt, ... file09.txt, file10.txt (note that the program is still called rename in Ubuntu, which can get confusing):
$ rename 's/file/file0/' file?.txt
But we can now do more interesting things. Say we have the following files, in Artist - Title.mp3 format.:
Cascada - Everytime We Touch.mp3 Darude - Sandstorm.mp3 Darude - Music.mp3 DJ Sammy & Yanou - Heaven.mp3
Let's say I want to switch around the order, so that I end up with Title - Artist.mp3:
$ rename 's/(.*) - (.*)\.mp3/$2 - $1.mp3/' *.mp3
Assuming my filenames are well-formatted and don't contain extraneous hyphens, now I'm left with:
Everytime We Touch - Cascada.mp3 Music - Darude.mp3 Heaven - DJ Sammy & Yanou.mp3 Sandstorm - Darude.mp3
To revert, just run the same command again.
Good old mv
The previous two file renaming utilities handle renaming files and directories, but they do not move files and cannot (as far as I know) rename files based on where they are in the directory structure. For this, we can rely on good old mv.
Let's say you have the following directory tree, organized by Artist/Album/Title:
Cascada/ |--Everytime We Touch/ |--Everytime We Touch.mp3 Darude/ |--Before the Storm/ | |--Sandstorm.mp3 |--Rush/ |--Music.mp3 DJ Sammy & Yanou/ |--Heaven/ |--Heaven.mp3
Now let's say I want all my files to be named Artist - Album - Title.mp3 and to all be in the same directory. This looks pretty messy at first glance, but it's just very logically descending through the tree:
$ for artist in *; do for album in "$artist"/*; do album=`basename "$album"` for title in "$artist/$album/"*.mp3; do mv "$title" "$artist - $album - `basename "$title"`" done done done
Now I have the files in one directory, plus empty directories where the
files used to be (which are easily removed with rm -rf */
—
just don't forget the trailing slash!):
Cascada - Everytime we Touch - Everytime We Touch.mp3 Darude - Before the Storm - Sandstorm.mp3 Darude - Rush - Music.mp3 DJ Sammy & Yanou - Heaven - Heaven.mp3 Cascada/ |--Everytime We Touch/ Darude/ |--Before the Storm/ |--Rush/ DJ Sammy & Yanou/ |--Heaven/
I'll leave undoing this as an exercise for the reader =)