I have a series of directories containing multiple mp3 files with filenames 001.mp3, 002.mp3, ..., 030.mp3.
What I want to do is to put them all together in order into a single mp3 file and add some meta data to that.
Here's what I have at the moment (removed some variable definitions, for clarity):
#!/bin/bash
for d in */; do
cd $d
find . -iname '*.mp3' -exec lame --decode '{}' - ';' | lame --tt "$title_prefix$name" --ty "${name:5}" --ta "$artist" --tl "$album" -b 64 - $final_path"${d%/}".mp3
cd ..
done
Sometimes this works and I get a single file with all the "tracks" in the correct order.
However, more often than not I get a single file with all the "tracks" in reverse order, which really isn't good.
What I can't understand is why the order varies between different runs of the script as all the directories contain the same set of filenames. I've poured over the man page and can't find a sort option for find.
I could run find . -iname '*.mp3' | sort -n >> temp.txt
to put the files in a temporary file and then try and loop through that, but I can't get that to work with lame.
Is there any way I can put a sort in before find runs the exec? I can find plenty of examples here and elsewhere of doing this with -exec ls
but not where one needs to execute something more complicated with exec.
The sort command sorts the contents of a file, in numeric or alphabetic order, and prints the results to standard output (usually the terminal screen). The original file is unaffected. The output of the sort command will then be stored in a file named newfilename in the current directory.
The sort command arranges data alphabetically or numerically in ascending or descending order. The grep command displays or hides only the required information you want.
Sort a File Numerically To sort a file containing numeric data, use the -n flag with the command. By default, sort will arrange the data in ascending order. If you want to sort in descending order, reverse the arrangement using the -r option along with the -n flag in the command.
find . -iname '*.mp3' -print0 | sort -zn | xargs -0 -I '{}' lame --decode '{}' - | lame --tt "$title_prefix$name" --ty "${name:5}" --ta "$artist" --tl "$album" -b 64 - $final_path"${d%/}".mp3
Untested but might be worth a try.
Normally xargs
appends the arguments to the end of the command you give it. The -I
option tells it to replace the given string instead ({}
in this case).
Edit: I've added -print0
, -z
, -0
to make sure the pipeline still works even if your filenames contain newlines.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With