Some of my music had no interpreter and title tags set thus I wrote a little shell script to batch edit these ID3 tags. The filenames of the songs looked like “01 Interpret – Song Title.mp3″. In a few moments I wrote the following php script1 which split the filename into the interpreter and the title.
All the python scripts listed here are using the library pytagger.
Unfortunately I forgot to strip the digits so all the interpreters had two leading digits afterwards.
I had to iterate over the files again. As id3.py creates new tag frames I had to write another script (fix_interpreters.py) that reads the old frames to get the old values.
#!/usr/bin/env python from tagger import * import sys, os, fnmatch, pickle, re filename = sys.argv print "Processing '", filename, "'" try: id3 = ID3v2(filename) if id3.tag_exists(): interpret_frame = None for frame in id3.frames: interpretfid = 'TPE1' if id3.version == 2.2: interpretfid = 'TP1' if frame.fid == interpretfid: interpret_frame = frame break interpret = interpret_frame.strings repaired = re.sub('^\d\d\s', '', interpret) print "Repairing \"", interpret, "\" => \"",repaired,"\"" interpret_frame.set_text(repaired) # replace interpret frame id3.frames = [frame for frame in id3.frames if frame.fid != interpretfid] id3.frames.append(interpret_frame) id3.commit(pretend=0) except ID3Exception, e: print("ID3 exception: %s" % str(e))
I didn’t want to rewrite the php script above because I thought that typing a loop in the shell would be easier (or at least faster).
for file in `ls -1 *.mp3`; do ./fix_interpreters.py $file; done
I tried it with this loop but ls -1 *.mp3 doesn’t list each mp3 file one per line as expected. Instead it splits the filenames after each whitespace. Thankfully to Greg Miller’s post about Handling Filenames With Spaces this wasn’t no problem anymore. I changed the loop into
find ./ -name '* *' | while read filename; do ls -ld "$filename"; ./fix_interpreters.py "$filename"; done
and ta-da, it worked.
- PHP scripts can be executed in a shell. Use php -f script.php to execute a file or use -r instead of -f to run inline code. ↩