因此,我尝试制作一个简单的脚本,该脚本采用源目录和目标目录作为参数,并在目标位置创建相同的目录结构,然后转换源中的每个文件,并将其放入相应的目标目录中GNU 并行命令。
我的脚本如下所示:
#!/bin/bash
SOURCE=$1
DEST=$2
find $SOURCE -type f -name '*.flac' -printf "%P\n" | parallel --dry-run mkdir -p $DEST{//}
find $SOURCE -type f -name '*.flac' -printf "%P\n" | parallel --dry-run ffmpeg -loglevel info -i {} -codec:a libmp3lame -qscale:a 3 $DEST{/.}.mp3
好极了!mkdir 工作正常(是的,mkdir 将尝试为每个文件创建一个目录,目前我对此表示满意)。
但是,在 ffmpeg 行上,输出不会以 $DEST 结束。事实上,$DEST 似乎为空,因为它没有出现在我的 --dry-run 输出中。
因此,当我写这篇文章时,我想到了一个想法,并使用了 ffmpeg 行的简化替换来尝试一下:
find $SOURCE -type f -name '*.flac' -printf "%P\n" | parallel --dry-run echo {} $DEST{/.}.mp3
也看到了同样的行为。凉爽的。然后我移动到 $DEST 所在的位置,如下所示:
find $SOURCE -type f -name '*.flac' -printf "%P\n" | parallel --dry-run echo {} {$DEST/.}.mp3
令人惊讶的是,将 $DEST 移动到 {/.} 中是有效的!但是,在 MKDIR 情况下尝试相同的技巧(例如 {$DEST//})是行不通的。
那么为什么 MKDIR 情况只能使用 $DEST{//},而简化情况只能使用 {$DEST/.}?
谢谢!
答案1
所以我一直在玩这个剧本,感觉就像我瞄准了一个移动的目标。我没有密切跟踪我的更改和其他情况,因此可能还存在其他问题。
不过,我认为我已经修复了我的脚本以使其正常工作。
该脚本的目标是获取包含 *.flac 和 *.jpg 文件的任意源目录,在目标位置创建相同的目录结构,然后重新编码该源中的所有 *.flac 文件,并写入目标目录中的 *.mp3。最后将源目录下的所有*.jpg(封面)复制到对应的目标目录中。尽可能使用GNU并行。
TL;DR - 使用并行将 FLAC 目录树转换为 MP3 目录树。
这就是我最终想出的
#!/bin/sh
SOURCE=$1
DEST=$2
find $SOURCE -type f -name '*.flac' -printf "%h\n" | uniq | parallel --dry-run mkdir -p {=s:$SOURCE:$DEST:g=}
find $SOURCE -type f -name '*.flac' -printf "%P\n" | parallel --dry-run ffmpeg -loglevel info -i $SOURCE{} -codec:a libmp3lame -qscale:a 3 $DEST{.}.mp3
find $SOURCE -type f -name '*.jpg' -printf "%P\n" | parallel --dry-run cp $SOURCE{} $DEST{}
它似乎有效,至少对于 --dry-run 输出来说是这样,如上所述。请随意(重新)使用它。