を使用して、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}")
二重引用符は、内容全体を単一の長い文字列として処理するようにシェルに指示するため、配列に単一の要素として格納されるため、一連の引数ではなく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は基本的にトークン化を実行しないので、技術的には引用は全く必要ありませんが、他のシェルと互換性のある引用スタイルに従うことを好むので、すべての変数拡張を引用します。
#!/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