를 사용하여 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