Normalizing your MP3 collection with mp3gain
find . -type f -iname '*.mp3' -print0 | xargs -0 mp3gain -r -k
Unfortunately, this seems to have problems with very large collections (I suspect that the command line is being filled up), so here’s what I came up with:
find . -iname '*.mp3' -execdir mp3gain -r -k "{}" \; &
If you’d rather use album normalization (and you have your files separated by album such as “~/Music/David Bowie/Hunky Dory”/):
find . -iname '*.mp3' -execdir mp3gain -r -k -a "{}" + &
How to use it
Simply open a terminal, browse to your music directory (using cd), and type it in.
Break it down
What the command does:
find . -iname '*.mp3'finds all MP3 files in the current directory and all subdirectories.-execdir mp3gain -r -k "{}" \; &executes “mp3gain -r -k” on each file (the filename goes where {} is found). The semi-colon indicates to execute the command once per file, but since ; is also a significant character for bash, you need to escape it with a backslash. The final ‘&’ tells bash to run the command in the background.

Thank you. I have added a link to this article for those who might be interested in your way of doing things.
Thank you for your guide
It really helps!
I just use:
for file in `find . -type f | grep mp3`; do mp3gain -q -k -p -r “$file”; done
I’m curious what the ‘+’ in the album command does? I think I understand all the rest of the command, and the -a is fairly easy to guess, but the change from ‘\;’ to ‘+’ is a mystery to me.
Mike: Check out the ‘find’ man page; you can use “-execdir … ;” which runs the command one file at a time, or “-execdir … +”, runs the command on all files in a directory at once.
I’ll try resubmitting the comment now that I know what the problem is.
Porges, your trackwise replaygain command will work fine but the album-based method will not do what you expect it to. In fact, it will do the exact same thing the trackwise command will. John’s for-loop command will work if there are no spaces in the file or directory names. Otherwise it will fail — or at least it did for me. After much mucking around, the following command did it for me:
Basically what it does it run mp3gain on EVERY subdirectory but only on the *.mp3 files contained therein. This is necessary because mp3gain will not accept a directory as an argument (unlike vorbisgain). The “read” command is there to handle spaces in directory and file names. The equivalent command for vorbisgain is:
The comments are moderated, so I have to approve them before they will show
Thanks for pointing that out. The
findmanpage makes it seem like this is what should happen…Given this structure:
dir1/ file1.mp3 file2.mp3 dir3/ file3.mp3 file4.mp3… with ‘;’ the command is executed once for every file, and with ‘+’ the command is executed on
"file1.mp3 file2.mp3"and then"file3.mp3 file4.mp3".Whereas, as you say, the change seems to do nothing!
Edit: After more research, it seems that this is partly a bug in
findutils, and partly a misunderstanding of the ‘+’ modifier. It doesn’t guarantee that all files in the directories will be collected, and currently performs the exact same task as ‘;’!I realised that as soon as I submitted it with firefox. I immediately got some feedback from the site that my comment was awaiting approval. With Opera I got nothing at all… And yes I have cookies enabled (but they are deleted when I shut opera down). That’s where my confusion sprang from.
Oh just one more thing. For those who say that vorbisgain has a “-r” switch eliminatinf\g the need for find completely, it will only work if your collection is comprised of oggs only. It will choke (and quit) on the first non-ogg/vorbis file it sees.
There’s a GTK frontend for mp3gain, aacgain and vorbisgain. I’ve found it on the Ubuntu repositories. Doesn’t work with FLAC, though.
The GUI frontend is called easyMP3gain, BTW.