Bash: Working with filenames containing spaces

by Dhruba Bandopadhyay on Thu, 14 Jun 2012 12:56:02 +0000

Here’s a quick tip for part time bash hackers like me. Let’s say you want to iterate over all mp3′s in a directory and add a prefix string (the album name) to each filename. The only problem is that the fool who created these files has added spaces in the filenames (shock, horror, gasp).

Your first reaction may to be write something like below.

PREFIX="my-album-name"
for FILENAME in $(ls *.mp3); do
  mv -v "${FILENAME}" "${PREFIX} - ${FILENAME}"
done

On the face of it this looks like it should work but it doesn’t. Bash will iterate tokens split not only by filename but also by the spaces in each filename so you will get far more tokens than you expected and the move operation will go horribly wrong.

In fact the correct answer, upon investigation, emerges to be as below.

PREFIX="my-album-name"
find . -name '*.mp3' | while read FILENAME; do
  mv -v "${FILENAME}" "${PREFIX} - ${FILENAME#./}"; 
done

Note the use of parameter expansion in the destination filename: ${I#./}. This is necessary because by default the $FILENAME variable begins with ./ to say that it lives in the current directory so that code simply removes the smallest match of ./ from the beginning of the string. This was tested on OS X Lion only. Done.

Incidentally – this script was actually being used to prefix mp3 files (with album names) that belong to a new band I’ve just come across called LDUK. Check them out if you haven’t heard of them. They’re very good – twitter, facebook, youtube. My favourite tracks are Room of Anger Jungle and Artistic Vortex. You can also download three free full albums here.

{ 3 comments… read them below or add one }

Dmitry June 14, 2012 at 13:25

http://easytag.sourceforge.net/ Easy tag is your friend in managing your mp3′s!

Reply

Dhruba Bandopadhyay June 14, 2012 at 13:27

But then I would have lost out on the fun of doing my first three lines of code in the last three months!

Reply

Dmitry June 14, 2012 at 19:17

Uh oh, yeah then it was a right thing to do indeed ;)

Reply

Leave a Comment

Previous post:

Next post: