我在一个目录中有很多文件夹,每个文件夹包含 2 个 mp3 文件。据此我可以找到这些文件:
first=$(find ./*/* -type f | sort | awk 'NR % 2 == 1')
second=$(find ./*/* -type f | sort | awk 'NR % 2 == 0')
我想将每个文件夹中的第一个文件与第二个文件连接起来:
ffmpeg -i "concat:$first|$second" -c copy "both_"$first
我已经发现这个 stackoverflow 答案,但我不知道是否以及如何将它用于我的目的。
目录结构:
folder "files"
|
|--folder1
| |--001_001.mp3
| |--001_003.mp3
|
|--folder2
|--001_004.mp3
|--001_009.mp3
...
任何帮助将不胜感激。
答案1
find
我认为在这种情况下不依赖会更简单、更稳健。您有一个定义良好的目录结构,并且实际上没有理由使用find
它来遍历它,因为您确切地知道文件在哪里。
相反,使用 shell 循环:
for dirpath in files/*/; do
set -- "$dirpath"/*.mp3
ffmpeg -i "concat:$1|$2" -c copy "$dirpath/both_${1##*/}"
done
或者,
for dirpath in files/*/; do
(
cd "$dirpath"
set -- *.mp3
ffmpeg -i "concat:$1|$2" -c copy "both_$1"
)
done
这将循环遍历您的folder1
等folder2
目录,其中每个目录的路径名都是$dirpath
.对于每个目录路径名,循环体将扩展*.mp3
该目录中的通配模式,然后使用该模式的前两个匹配来运行命令ffmpeg
。没有进行任何检查来确保我们实际上获得了该模式的两个匹配项。
上面两个循环之间的区别在于,第一个循环不会将其目录更改为每个$dirpath
目录,因此$1
和$2
将包含该目录的目录路径。这就是为什么我用来"$dirpath/both_${1##*/}"
创建目录中调用的文件的路径both_something.mp3
(必须从开头删除目录路径$1
才能插入both_
子字符串)。
另一个循环用于cd
将目录更改为循环中的每个目录。这样,$1
和$2
字符串将是文件名而不是带有初始目录路径的路径名。由于cd
发生在子 shell (the (...)
) 内,工作目录的更改仅影响括号内的命令。