Gnu parallel: quoted arguments and spaces in file names. How to solve

ffmpeggnu-parallel

This is driving me crazy.

I have a bunch of mp3 that I want to transcode using ffmpeg.

I'm trying to use this one-liner (the script is bigger, this is the problematic section):

find . -type f \( -iname \*.mp3 \) | parallel ffmpeg -i "{}" -acodec libmp3lame -ab 128k "$output_folder_with_spaces/{.}-128k.mp3" \;

(The iname section is there because in the future more extensions will maybe be used)

But even using the quotes in {}, I always get No such file or directory, cause the mp3 is named 01 - My song. And I don't know if "$output_folder_with_spaces" is going to work either.

I've googled a lot, but can't find this example: using {} from find that {} has spaces. I've only found when using a variable or hardcoded paths in quotes.

Anyone knows how I can solve this space problem, in this scenario?

Best Answer

You are using the wrong replacement string with parallel; you'll also need -q to pass quoted arguments and I'm not sure what the trailing \; does...
Example:

dirname_with_spaces="/home/don/my dir with spaces/"

(note the trailing / in the path assigned to dirname_with_spaces) and some mp3 file names with spaces under a test directory, right under cwd:

./test/Commercial DEMO - 09.mp3
./test/Commercial DEMO - 11.mp3
./test/Handel Royal Fireworks - 07.mp3
./test/Jazz Rag Ensemble - 10.mp3
./test/Mouret - Rondeau.mp3

using

find . -type f -iname \*.mp3 | parallel -q ffmpeg -i {} -acodec \
libmp3lame -ab 128k "$dirname_with_spaces"{/.}-128k.mp3

produces the following files:

/home/don/my dir with spaces/Commercial DEMO - 11-128k.mp3
/home/don/my dir with spaces/Commercial DEMO - 09-128k.mp3
/home/don/my dir with spaces/Handel Royal Fireworks - 07-128k.mp3
/home/don/my dir with spaces/Jazz Rag Ensemble - 10-128k.mp3
/home/don/my dir with spaces/Mouret - Rondeau-128k.mp3

Note the command line quoting (parallel -q) and the usage of:

{}
    Input line.

which means the path from find output e.g. ./test/Mouret - Rondeau.mp3
and

{/.}
    Basename of input line without extension. 

which expands to Mouret - Rondeau and then "$dirname_with_spaces"{/.} expands to /home/don/my dir with spaces/Mouret - Rondeau

The latter is quite different from the {.} used in your command

{.}
    Input line without extension.

which would expand to ./test/Mouret - Rondeau and then "$dirname_with_spaces"{.} would expand to /home/don/my dir with spaces/./test/Mouret - Rondeau. Obviously, this will error out as there is no /./test/ under /home/don/my dir with spaces.

Related Question