I have a library of MP3 files where in some files the "CD number" tag (TPOS) contains "CDx" values, e.g. "CD1" or "CD2". The ID3 spec says that TPOS values shall be numerical strings. Processing these files breaks some tag editors, specifically eyeD3 ignores the values.

What would be a smart way to replace these ID3 tags with numeric strings, via command line?

I have a solution which comes with some command line magic, I am looking for something simpler:

find . -name "*.mp3" -exec id3v2 -R {} \; |awk -F": " '/^Filename/ {f=$2};/^TPOS/ {print f, "\t", $2}'|grep CD1|awk -F" \t" '{print $1}'|xargs -L 1 -d "\n" -I{} id3v2 --TPOS "1" {}

In a nutshell: find mp3 files, extract the ID3 tags with id3v2, extract filename and TPOS with awk, grep for "CD1", cut out the filename and apply id3v2 to set the disc number to "1".

  • 1
    If you're conversant with Perl, there's a CPAN module called MP3::Tag that should come in handy.
    – Joseph R.
    Dec 19, 2013 at 22:59
  • Well, next to Perl, I maybe could solve that with eyeD3 and its low level tag handling code. But since this is supposed to be a one-time activity, I put together that shell one-liner which ended being much longer than expected. So, I am curious if one can do that with less effort.
    – Bernd
    Dec 20, 2013 at 7:16

1 Answer 1


If file names don't contain newline characters, you could write it as:

exiftool -q -ext mp3 -if '$PartOfSet =~ /^CD\d+\z/' -p \
  '$PartOfSet:$Directory/$FileName' . | while IFS=: read -r p f; do
  id3v2 --TPOS="${p#CD}" "$f"; done

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .