Usando mkvmerge
, quiero agregar pistas de audio a varios clips MKV organizados así
Clips_folder
/spa/clip1.mka
/spa/clip2.mka
/ger/clip1.mka
/ger/clip2.mka
/clip1.mkv
/clip2.mkv
Ese es el guión que tengo (basado en 'Agregar argumento a la 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
Ese es el resultado:
-o ./output/clip1.mkv --language 0:eng clip1.mkv --language 0:spa ./spa/clip1.mka --language 0:ger ./ger/clip1.mka
Pero cuando lo cambio a mkvmerge ${audioargs[@]}
me sale
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: no destination file name was given
¿Cómo paso correctamente audioargs
a mkvmerge
para que se expanda a mkvmerge -o file --language ...
etc.?
Respuesta1
No tengo mkvmerge
que realizar pruebas, pero estoy bastante seguro de que el problema es cómo cita las cosas cuando crea la matriz. Cuando haces algo como
audioargs=("-o ./output/${video} --language 0:eng ${video}")
Las comillas dobles le dicen al shell que trate todo eso como una cadena larga, por lo que se almacena como un solo elemento en la matriz y, por lo tanto, se pasa mkvmerge
como un argumento único que contiene espacios, en lugar de una serie de argumentos.
Nota que echo
oculta la distinción entre un espacio dentro de un argumento y un espacioentreargumentos, lo que lo hace muy engañoso para cosas como esta. Ponerlo set -x
antes del comando debería aclarar lo que realmente está sucediendo. Con sus nombres de archivo de ejemplo, set -x
muestra lo que se está ejecutando:
echo '-o ./output/clip2.mkv --language 0:eng clip2.mkv' '--language 0:ger ./ger/clip2.mka' '--language 0:spa ./spa/clip2.mka'
¿Ves las secciones largas entre comillas simples? Así es como indica que se trata de argumentos largos que contienen espacios, en lugar de secuencias de argumentos separados.
Para resolverlo, simplemente use comillas normales cuando cree la matriz (es decir, las mismas comillas que usaría al pasar argumentos directamente al comando). zsh no divide palabras de forma predeterminada, por lo que técnicamente no es necesario citar ninguna cita, pero prefiero seguir el estilo de citación compatible con otros shells, por lo que cito todas las expansiones variables:
#!/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
Lo que da este resultado con set -x
:
echo -o ./output/clip2.mkv --language 0:eng ./clip2.mkv --language 0:ger ./ger/clip2.mka --language 0:spa ./spa/clip2.mka