Используя 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