Hello,

I'm kinda weird I know but I'm trying to encode my mp3 to a lower quality (for my mobile phone) with one line of shell (with bash). I'm wasting some more time as I would do by hand but I'm very interested. Here is my not-working line :

find -iname "*.mp3" | xargs -n1 -I{} -P5 -0 -p --delimiter='\n' lame -q1 --vbr-new -V6 -b 32 -B 128 {} /mnt/sda1/tmp-zik/\`basename {}\`

So the main problem in my command line is the way I would like to use basename but it isn't working as my expectation. The reason I use it is that I have as input (of xargs) the relative path of the files (let's say I'm in /mnt/mp3) and there are artist and album folders in it (example: /mnt/mp3/artist/album/file blabla 01 title.mp3). So xargs receive as input: ./artist/album/file blabla 01 title.mp3 in this case.

So the first parameter of lame (the input file) is correct but not the second one (the output file). So here I am: my basename is removed at runtime and won't have any effect. Moreover I have prepared a folder for the output files but without any folder tree: so all the files would be in one folder: /mnt/sda1/tmp-zik.

Can you share your experience or your idea to bypass this little problem ? I will greatly appreciate your help ! Thank you in advance.

Recommended Answers

All 4 Replies

I think you've misinterpreted the situation. The {} is specific to the find utility, and has no special meaning for xargs (in fact I wonder how they are parsed at all in this context). The latter forms the command by appending the input string (as a last argument) to the given set of arguments. To summarize, a filename is mentioned in the lame command line just once.
I don't think there's a one-line solution which involves xargs; you may consider the find's -exec option. If I were you, I'd make a small wrapper script to invoke lame properly.

For reasons I can't fathom basename doesn't appear to work with xargs, even though the {} is correct. The command below works for me, but I haven't dealt with the case where the filename has spaces in it.

[B]bash syntax[/B]

find . -iname "*.mp3" -printf "%p /mnt/sda1/tmp-zik/%f\n" | xargs -n2 -P5 -0 -p lame -q1 -b 32 -B 128

That is **awesome** ! Thank you for your reply, this printf option is so useful !

find mp3/ -iname "*.mp3" -printf "%p\n/mnt/sda1/tmp-zik/%f\n" | xargs -L1 -n2 -P5 -0 --delimiter='\n' lame -S -q1 --vbr-new -V6 -b 32 -B128

This is working on my 4 CPU as hell. This is the best way to encode a massive group of files. Thank you.

If you have GNU Parallel installed:

find mp3/ -iname "*.mp3" -printf "%p\n/mnt/sda1/tmp-zik/%f\n" | parallel -n2 -j+0 lame -S -q1 --vbr-new -V6 -b 32 -B128

Watch the intro video to learn more: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.