gnu parallel:文件名中带引号的参数和空格。怎么解决?

Som*_*DOS 6 ffmpeg gnu-parallel

这真让我抓狂。

我有一堆 mp3,我想使用ffmpeg.

我正在尝试使用这个单行(脚本更大,这是有问题的部分):

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

(该iname部分存在是因为将来可能会使用更多扩展)

但即使使用 中的引号{},我也总是得到No such file or directory,因为 mp3 被命名为01 - My song. 我也不知道是否"$output_folder_with_spaces"会起作用。

我GOOGLE了很多,但无法找到这个例子:使用{}来自find{}有空格。我只发现在引号中使用变量或硬编码路径时。

有谁知道在这种情况下我如何解决这个空间问题?

don*_*sti 6

您使用了错误的替换字符串parallel;你还需要-q传递带引号的参数,我不确定尾随的\;作用......
例如:

dirname_with_spaces="/home/don/my dir with spaces/"
Run Code Online (Sandbox Code Playgroud)

(注意/分配给 的路径中的尾随dirname_with_spaces)和目录mp3下的一些带有空格的文件名test,就在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
Run Code Online (Sandbox Code Playgroud)

使用

find . -type f -iname \*.mp3 | parallel -q ffmpeg -i {} -acodec \
libmp3lame -ab 128k "$dirname_with_spaces"{/.}-128k.mp3
Run Code Online (Sandbox Code Playgroud)

产生以下文件:

/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
Run Code Online (Sandbox Code Playgroud)

注意命令行quoting ( parallel -q) 和使用:

{}
    Input line.
Run Code Online (Sandbox Code Playgroud)

这意味着来自find输出的路径,例如./test/Mouret - Rondeau.mp3

{/.}
    Basename of input line without extension. 
Run Code Online (Sandbox Code Playgroud)

扩展到Mouret - Rondeau然后 "$dirname_with_spaces"{/.}扩展到/home/don/my dir with spaces/Mouret - Rondeau

后者{.}与您的命令中使用的完全不同

{.}
    Input line without extension.
Run Code Online (Sandbox Code Playgroud)

这将扩展到./test/Mouret - Rondeau然后 "$dirname_with_spaces"{.}将扩展到/home/don/my dir with spaces/./test/Mouret - Rondeau. 显然,这会出错,因为没有/./test/under /home/don/my dir with spaces


der*_*ert 2

您误解了find\的语法。该{}语法与 结合使用-exec。另外,你不需要那些括号;仅当您想覆盖默认的操作顺序(例如,不从左到右评估)时才需要它们。总的来说,对于 exec,它看起来像这样(分割以避免水平滚动):

\n\n
find . -type f -iname \\*.mp3 -exec \\\n    ffmpeg -i "{}" -acodec libmp3lame -ab 128k \\\n    "$output_folder_with_spaces/{}-128k.mp3" \\;\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,将为您提供名为foo.mp3-128.mp3\xe2\x80\xa6 的文件,我希望这就是您想要的;我不知道{.}\xe2\x80\x94\x94 它的语法无效,至少对于 GNU find 来说是这样。

\n\n

我建议lame直接使用,而不是通过 FFmpeg(如果-ab使用 ABR 模式而不是 VBR 模式,我会建议在没有充分理由的情况下反对)。实际上,我建议不要对 MP3 进行重新编码;通过从无损源进行编码,可以在相同比特率下获得更好的质量。

\n