Home > Uncategorized > Parsing ID3 tags in Bash and renaming MP3s

Parsing ID3 tags in Bash and renaming MP3s

January 29, 2011 Leave a comment Go to comments

(Subtitle: Using Bash when I probably shouldn’t…)

First, let’s define a bunch of useful functions.  We’ll later use these functions to extract the relevant sections of our ID3 tags.  I’m going to assume you are using your interpreter directly, so lets copy & paste the following lines straight into your terminal:

function tag() { tail -c 128 "$1" | head -c 3; }
function title() { tail -c 125 "$1" | head -c 30 | rtrim; }
function artist() { tail -c 95 "$1" | head -c 30 | rtrim; }
function album() { tail -c 65 "$1" | head -c 30 | rtrim; }
function year() { tail -c 35 "$1" | head -c 4 | rtrim; }
function comment() { tail -c 31 "$1" | head -c 28 | rtrim; }
function track() { tail -c 3 "$1" | hexdump -ve '/1 "%02i "' \
                   | awk '{ if ($1 == 0 && $2 != 0) print $2" " }'; }
function genre() { tail -c 1 "$1" | hexdump -ve '/1 "%03i"'; }

function rtrim() { sed 's/\([^ ]*\) *$/\1/'; }
function filt() { tr -d '/*?'; }

Now lets say the current directory is full of MP3s that we would like to move to an appropriate folder and give a more appropriate filename (in my case, I had my corrupt old iPod from which I was attempting to extract all the music I could).  The structure I’m aiming for is:

ARTIST – ALBUM / TRACK_NUMBER ARTIST – SONG_NAME

Making use of our functions defined above, this for loop ought to do the trick:

for file in *.mp3; do [ "$(tag "$file")" == "TAG" ] && \
    (  artist="$(artist "$file" | filt)"; \
       album="$(album "$file" | filt)"; \
       title="$(title "$file" | filt)"; \
       track="$(track "$file" | filt)"; \
       dir="$artist - $album"; \
       newfile="$track$artist - $title.mp3"; \
       \
       mkdir -p "$dir"; \
       mv "$file" "$dir/$newfile"); \
    done

And indeed this “one liner” did a reasonable job on my MP3 collection, YMMV.

Of course this only works for ID3v1 tags and doesn’t support “extended” v1 tags.

I can’t imagine ID3v2 possibly being parsed in bash, but I’d like to be proved wrong :-)

About these ads
  1. dericbytes
    September 10, 2011 at 10:20 pm

    cool

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: