One Line Batch Rename Files Using CSV Input File and awk


The Bash command environment, which is the namesake of this blog, is very flexible in that it allows you to manipulate the filesystem in many ways. Awk and sed are very powerful tools that allow you to do this rename with a simple one line command. This post will walk you through doing this with a Comma Separated Value (CSV) file and also using a simple regular expression to rename many files.

The goal is  to rename a whole folder, hundreds of files, to a proper format for viewing in Boxee. The old listing, for example using ls -1, was:

Seinfeld-(The Wig Master)-2003-09-26-0(1).avi
Seinfeld-(The Wink)-2004-01-03-0.avi
Seinfeld-(The Wizard)-2004-02-26-0.avi
Seinfeld-(The Yada Yada)-2003-06-04-0.avi
Seinfeld-(The Pen)-2004-06-22-0.avi

I created a CSV file, and from the powers of the Amazon Mechanical Turk services, generated an entire list of the correct filenames, in the format:


Now I just needed a way to actually do the rename.

The final CSV file I generated is in the format:

Seinfeld-(The Wig Master)-2003-09-26-0(1).avi,Seinfeld.7x19.The.Wig.Master.avi
Seinfeld-(The Wink)-2004-01-03-0.avi,Seinfeld.7x04.The.Wink.avi
Seinfeld-(The Wizard)-2004-02-26-0.avi,Seinfeld.9x15.The.Wizard.avi
Seinfeld-(The Yada Yada)-2003-06-04-0.avi,Seinfeld.8x19.The.Yada.Yada.avi
Seinfeld-(The Pen)-2004-06-22-0.avi,Seinfeld.3x03.The.Pen.avi

Note that in my format, there could be no commas in the file names; but you can use any other delimiter such as = or ;, it would work equally as well with a character change in the script.

Using awk, you can get a correct command line output from this file:

awk -F',' '{print("mv \"" $1 "\" \"" $2 "\"")}' input.txt

Results in a preview of your commands, like so:

mv "Seinfeld-(The Wig Master)-2003-09-26-0(1).avi" "Seinfeld.7x19.The.Wig.Master.avi"
mv "Seinfeld-(The Wink)-2004-01-03-0.avi" "Seinfeld.7x04.The.Wink.avi"
mv "Seinfeld-(The Wizard)-2004-02-26-0.avi" "Seinfeld.9x15.The.Wizard.avi"
mv "Seinfeld-(The Yada Yada)-2003-06-04-0.avi" "Seinfeld.8x19.The.Yada.Yada.avi"
mv "Seinfeld-(The Pen)-2004-06-22-0.avi" "Seinfeld.3x03.The.Pen.avi"

Note that we put the file names in quotes because they contain spaces, and linux won’t recognize the filenames if you don’t include that. The -F command in awk is where you specify your delimiter, so feel free to use another character. Once you have ‘proofed’ the script to make sure it is doing what you expect it to, you execute it by adding |/bin/sh to the end, to pipe it directly to bash.

awk -F',' '{print("mv \"" $1 "\" \"" $2 "\"")}' input.txt | /bin/sh

This won’t result in any output, but you will see that it changed the names of your files, just as if you would have typed in the commands (proofed above) yourself.

If you don’t want to go through the bother of generating a CSV file, but you still want to use bash to rename files using awk, you can use a similar command which I found over at Snipplr.

ls foo*.jpg | awk '{print("mv "$1" "$1)}' | sed 's/foo/bar/2'

As with the other one, this will output the command to move the file but instead uses sed to do a search/replace of the string in the filename. Append |/bin/sh to execute the commands on your system.