Usando mkvmerge
, quero adicionar faixas de áudio a vários clipes MKV organizados assim
Clips_folder
/spa/clip1.mka
/spa/clip2.mka
/ger/clip1.mka
/ger/clip2.mka
/clip1.mkv
/clip2.mkv
Esse é o script que eu tenho (baseado em 'Anexar argumento à lista de argumentos'):
#!/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
Essa é a saída:
-o ./output/clip1.mkv --language 0:eng clip1.mkv --language 0:spa ./spa/clip1.mka --language 0:ger ./ger/clip1.mka
Mas quando eu mudo para mkvmerge ${audioargs[@]}
eu fico
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: no destination file name was given
Como passo corretamente audioargs
para mkvmerge
que seja expandido para mkvmerge -o file --language ...
etc?
Responder1
Não preciso mkvmerge
testar, mas tenho certeza de que o problema é como você cita as coisas ao construir o array. Quando você faz algo como
audioargs=("-o ./output/${video} --language 0:eng ${video}")
As aspas duplas dizem ao shell para tratar tudo como uma longa string, então ela é armazenada como um único elemento no array e, portanto, passada mkvmerge
como um único argumento contendo espaços, em vez de uma série de argumentos.
Observe que isso echo
esconde a distinção entre um espaço dentro de um argumento e um espaçoentreargumentos, tornando-o altamente enganoso para coisas como esta. Colocar set -x
antes do comando deve esclarecer o que realmente está acontecendo. Com seus nomes de arquivos de exemplo, set -x
mostra o que está sendo executado:
echo '-o ./output/clip2.mkv --language 0:eng clip2.mkv' '--language 0:ger ./ger/clip2.mka' '--language 0:spa ./spa/clip2.mka'
Veja as longas seções entre aspas simples? É assim que indica que são argumentos longos contendo espaços, em vez de sequências de argumentos separados.
Para resolver isso, basta usar aspas normais ao construir o array (ou seja, as mesmas aspas que você usaria ao passar argumentos diretamente para o comando). zsh não divide palavras por padrão, então tecnicamente você não precisa citar nada, mas eu prefiro seguir o estilo de cotação compatível com outros shells, então cito todas as expansões de variáveis:
#!/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 que dá esse resultado com set -x
:
echo -o ./output/clip2.mkv --language 0:eng ./clip2.mkv --language 0:ger ./ger/clip2.mka --language 0:spa ./spa/clip2.mka