Tuesday, June 17, 2014

How to rename files in bulk

Consider this common scenario. A directory contains multiple files that are named using a common convention: for example, image-001.png, image-002.png, image-003.png, etc. You want to rename the files to, say, upload-001.png, upload-002.png, upload-003.png, etc.

The coders among us can write a bash script to automate the process. For expedience, this post shows how to use the built-in rename command to achieve the same goal.

The following command replaces the first occurrence of image with upload in the file name for all PNG files in the current directory.

$ rename -v 's/image/upload/' *.png image-001.png renamed as upload-001.png image-002.png renamed as upload-002.png image-003.png renamed as upload-003.png

Notes:

  • -v

    Produce verbose output, listing each file with its old and new names.

  • 's/image/upload/'

    Provide a valid PERL expression to modify the file names.

  • *.png

    Specify the files to be renamed.

The full power of PERL expressions is at your disposal to specify the file renaming rule. A thorough explanation of PERL expressions is beyond the scope of this post. The following only samples some useful PERL expressions.

  • Global replace.

    If you want to replace ALL occurrences of a pattern in a file name, you must specify a global replace. For example, you want to replace all spaces in the file names with null, that is, delete all spaces.

    $ rename -v 's/ //g' *.pdf Boarding Pass - Derek 2014-05-19.pdf renamed as BoardingPass-Derek2014-05-19.pdf Boarding Pass - Erin 2014-05-19.pdf renamed as BoardingPass-Erin2014-05-19.pdf capture_still_frame (1).pdf renamed as capture_still_frame(1).pdf capture_still_frame (2).pdf renamed as capture_still_frame(2).pdf
  • Match any character in a list.

    Suppose you want to replace all occurrences of spaces, underscores, and round brackets with the dash character. Here is how.

    $ rename -v 's/[_ ()]/-/g' *.pdf

    Any character within the square brackets is matched, and replaced by a dash.

  • Back reference variables.

    Suppose the file names follow this convention: prefix-sequence.suffix. For instance, usa-001.png. My task is to switch the order of the prefix and the sequence number, resulting in names such as 001-usa.png. You can achieve the result by using back reference variables as follows:

    $ rename -v 's/(.+)-([0-9]{3})/$2-$1/' *.png india-003.png renamed as 003-india.png uk-002.png renamed as 002-uk.png usa-001.png renamed as 001-usa.png

    The above example has 2 back reference variables separated by a dash: $1 and $2. The first variable $1 is defined by (.+), which means 1 or more characters. The second variable $2 is defined by ([0-9]{3}), which means exactly 3 digits, each digit being from 0 to 9. The replacement pattern, $2-$1, specifies that $2 now comes before $1, with a dash in between.

To avoid potential mistakes, you can first do a mock run of the rename command before actually running it for real. Specify the -n option, which stands for 'no-act'.

$ rename -n 's/image/upload/' *.png image-001.png renamed as upload-001.png image-002.png renamed as upload-002.png image-003.png renamed as upload-003.png

If all the suggested replacements look reasonable, then go ahead to run the command without the -n.

1 comment:

Notes On Using Linux said...

Great post. I do a lot of stuff with photography and graphics and have just started to really try and use the power of Linux to organize and search my folders. I'm trying to organize a lot of my stuff with shotwell, and search by tags, but I think I'm going to incorporate this into my file naming.

This will be perfect for naming my photos by styles, like sunset-001.jpg sunset-002.jpg etc. The same goes for my graphics projects.

Thanks for the great article and love your blog !