使用mkvmerge
,我想将音轨添加到几个像这样排列的 MKV 剪辑中
Clips_folder
/spa/clip1.mka
/spa/clip2.mka
/ger/clip1.mka
/ger/clip2.mka
/clip1.mkv
/clip2.mkv
这就是我的脚本(基于“将参数附加到参数列表”):
#!/bin/zsh
mkdir -p output
for video in *.mkv
do
audioargs=("-o ./output/${video} --language 0:eng ${video}")
for audiodir in *(/)
do
audioargs+=("--language 0:${audiodir} ./${audiodir}/${video:r}.mka")
done
echo ${audioargs[@]}
done
这就是输出:
-o ./output/clip1.mkv --language 0:eng clip1.mkv --language 0:spa ./spa/clip1.mka --language 0:ger ./ger/clip1.mka
但是当我把它改成mkvmerge ${audioargs[@]}
我得到
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: no destination file name was given
我如何正确地传递audioargs
到mkvmerge
以便它扩展到mkvmerge -o file --language ...
等?
答案1
我不必mkvmerge
进行测试,但我很确定问题在于构建数组时如何引用内容。当你做类似的事情时
audioargs=("-o ./output/${video} --language 0:eng ${video}")
双引号告诉 shell 将整个事情视为一个长字符串,因此它作为单个元素存储在数组中,因此mkvmerge
作为包含空格的单个参数传递,而不是一系列参数。
请注意,echo
隐藏了参数内的空格和空格之间的区别之间争论,使其对此类事情具有高度误导性。放在set -x
命令之前应该澄清实际发生的情况。使用您的示例文件名,set -x
显示正在运行的内容:
echo '-o ./output/clip2.mkv --language 0:eng clip2.mkv' '--language 0:ger ./ger/clip2.mka' '--language 0:spa ./spa/clip2.mka'
看到长长的单引号部分了吗?这就是它指示这些是包含空格的长参数,而不是单独参数的序列的方式。
要解决这个问题,只需在构建数组时使用正常的引用(即直接将参数传递给命令时使用的引用相同)。 zsh 默认情况下不会进行分词,因此从技术上讲,您根本不需要引用,但我更喜欢遵循与其他 shell 兼容的引用风格,因此我引用了所有变量扩展:
#!/bin/zsh
mkdir -p output
for video in *.mkv
do
audioargs=(-o "./output/${video}" --language 0:eng "./${video}")
for audiodir in *(/)
do
audioargs+=(--language "0:${audiodir}" "./${audiodir}/${video:r}.mka")
done
echo "${audioargs[@]}"
done
结果如下set -x
:
echo -o ./output/clip2.mkv --language 0:eng ./clip2.mkv --language 0:ger ./ger/clip2.mka --language 0:spa ./spa/clip2.mka