Malleable Renaming Script

Update:

I have vastly improved my renaming script and published it to GitHub for your convenience.

FileRename.sh

Original article:

I often get a pile of files where the original maker of those files used some naming scheme which, like spoiled milk, offends my nostrils.  You may call me anal if you’d like, but it prompted me to write this useful script so consider that before you start pointing fingers and laughing.

Essentially this script is set up so that I can easily open it in a text editor, make any changes, save it, and then run it on some folder.  Here it is and we’ll talk a bit below about how to use it.

(Use the pointy brackets button to copy and paste.)

##
#!/bin/bash
# Substitute one string for another within a file name
# by JamesIsIn from JamesIsIn.com
# Do something nice today.

#for filename in *
for filename in */*.[Ff][Ll][Aa][Cc]
#for filename in */*.[Mm][Pp]3
#for filename in */*.[Oo][Gg][Gg]
   do
   mv "$filename" "${filename/ - / – }"
   echo $filename changed
done

exit

 - – 

##

(Please note that your browser will likely not make a distinction between the hyphen (-) and the dash (–) in this post. However, if you click on the double-pointy-bracket button in the code box above you will be able to copy the correct code.)

Ok, so what we have here, after my usual header section, is four possible for loops. Three of them are commented out (since you’ll only be using one at a time), but they are pretty strait-forward.

The first one seeks anything in the current directory (know where you are!) and uses that as input. I use this first one for changing folder names, but be careful because it will change all folders and files that match the pattern which follows. The next three for loops are for three different kind of audio file (FLAC, OGG, and MP3). Since the capital and lower-case letters are in square brackets this means the shell is offered a choice. This is one method for eliminating case-sensitivity (there are others).

After the for loop begins and files/folders are sought out which match the patter under in we have to do something. In this case the script does two somethings: mv and echo (which mean “move” and “display in the terminal” basically).

The variable (here called filename) is then used to stimulate a substitution. Let’s dissect the substitution briefly. In the case shown above the shell will attempt to replace space-hyphen-space with space-dash-space in any flac file it finds in any folder below the current directory.

Why?

First */*.[Ff][Ll][Aa][Cc] tells us, in more human terms, look into any folder (*/) below the current directory for anything (*) that ends in .flac (.[Ff][Ll][Aa][Cc]). When you find one (do) replace the first (/) space-hyphen-space () with (/) space-dash-space () and that’s it (/).

If instead you use “${filename// – / – }” this means when you find one (do) replace all occurrences (//) of space-hyphen-space () with (/) space-dash-space () and that’s it (/).

There is no need to echo the work, but I like to see what it’s doing (or what it’s failed to do). It’s useful but not required. Also the exit command is not, strictly speaking, required; but I use it in this script especially so that I can store characters below it and thereby keep them around for use in the script ( – – ).

Let’s look at an example of this script in use.

Suppose you downloaded (legally, you sneaky bastards) a copy of Jay Farrar and Benjamin Gibbard’s One Fast Move or I’m Gone (Music from Kerouac’s Big Sur). Further suppose that the yahoo who made the flac files insisted on including the artist names on every track. Silly because you keep your collection organized and the album is in a folder with the album name which is in a folder with the artist name. So you’d like to remove the artist names from all the tracks. You could do that by hand for each track, but this is a perfect opportunity for a script so…

The tracks are currently Jay Farrar & Benjamin Gibbard 01 California Zephyr.flac and so your script would look like this:

(Use the pointy brackets button to copy and paste.)

##
#!/bin/bash
# Substitute one string for another within a file name
# by JamesIsIn from JamesIsIn.com
# Do something nice today.

#for filename in *
for filename in */*.[Ff][Ll][Aa][Cc]
#for filename in */*.[Mm][Pp]3
#for filename in */*.[Oo][Gg][Gg]
   do
   mv "$filename" "${filename/Jay Farrar & Benjamin Gibbard /}"
   echo $filename changed
done

exit

 - – 

##

Note two things. First there is a space after Gibbard. Fail to include that and all your tracks begin with a space. Second there is nothing between the slash and the curly-bracket. This means “replace Jay-space-Farrar-space-ampersand-space-Benjamin-space-Gibbard-space” with nothing (or delete it, eh?). This will leave your tracks looking more like 01 California Zephyr.flac .

If you are like me, you like having a dash between the track number and the track name. Others might prefer to use a dot. So for inserting a dash or a dot in the first occurrence of a space that line would look like this:

mv “$filename” “${filename/ / – }”

mv “$filename” “${filename/ /. }”

To run the script open a terminal and move (cd) into the artist folder keeping in mind it would change any other album folder contents—but I know these guys only put out one ablum in this configuration. If you are worried about changing other albums move into the album folder and remove the */ before the *.extension and the script will act on the current directory. When you are in the directory you want, run the script by name (I call mine RemoveModifiable.sh). Be sure the script has execute permissions.

Do be careful with this script. It can be really powerful and can leave you staring at a folder full of files called 01.flac pretty quickly (or several folders if you use the */ construction I am above). As always, work from copies. After all scripts are supposed to make your life easier.

Share

One thought on “Malleable Renaming Script

  1. I ran into an issue again that has troubled me in the past. I had a bunch of different folder/file combinations to remove information from which had a recognizable pattern but one which my usual combination of replacements would bork. Here is an example:

    The Black Keys – Chulahoma – 01 – Keep Your Hands Off Her.flac

    I don’t want the band and album names in the file name. I’d like to remove them from all the albums. Let’s say there are five different albums. I’d have to alter my script for each album (name) and remove those prepended strings.

    I wanted to run the script once. If I were to run this:

    mv “$filename” “${filename/The Black Keys – * – /}”

    I would end up with files named as such:

    Keep Your Hands Off Her.flac

    That’s removing too much. The asterisk, though doing it’s job of acting as any number of characters (including zero characters), is rushing right past that next ” – ” and chopping too much off the file names. Instead I used this:

    mv “$filename” “${filename/The Black Keys – *[!0-9] – /}”

    What this says is replace the string “The Black Keys – [AnyNumberOfCharacters][AnySingleCharacterThatIsNOTaNumber] – ” with nothing.

    Now you know.

Leave a Reply

Your email address will not be published. Required fields are marked *