Batch renaming

Contents

  1. util-linux(-ng) rename
  2. prename
  3. Good old mv

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 =)