Mit mkvmerge
möchte ich Audiospuren zu mehreren MKV-Clips hinzufügen, die wie folgt angeordnet sind
Clips_folder
/spa/clip1.mka
/spa/clip2.mka
/ger/clip1.mka
/ger/clip2.mka
/clip1.mkv
/clip2.mkv
Das ist das Skript, das ich habe (basierend auf „Argument an Argumentliste anhängen“):
#!/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
Das ist die Ausgabe:
-o ./output/clip1.mkv --language 0:eng clip1.mkv --language 0:spa ./spa/clip1.mka --language 0:ger ./ger/clip1.mka
Aber wenn ich es ändere, mkvmerge ${audioargs[@]}
bekomme ich
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: no destination file name was given
Wie übergebe ich richtig audioargs
an mkvmerge
, sodass es zu mkvmerge -o file --language ...
usw. erweitert wird?
Antwort1
Ich muss es nicht mkvmerge
testen, aber ich bin mir ziemlich sicher, dass das Problem darin liegt, wie Sie Dinge in Anführungszeichen setzen, wenn Sie das Array erstellen. Wenn Sie so etwas tun wie
audioargs=("-o ./output/${video} --language 0:eng ${video}")
Die Anführungszeichen weisen die Shell an, das Ganze als einen langen String zu behandeln, sodass es als einzelnes Element im Array gespeichert und daher mkvmerge
als einzelnes Argument mit Leerzeichen und nicht als Reihe von Argumenten übergeben wird.
Beachten Sie, dass echo
der Unterschied zwischen einem Leerzeichen innerhalb eines Arguments und einem Leerzeichen ausgeblendet wird.zwischenArgumente, was es für solche Dinge höchst irreführend macht. Wenn man es set -x
vor den Befehl setzt, sollte klar sein, was tatsächlich passiert. Mit Ihren Beispieldateinamen set -x
zeigt es, was ausgeführt wird:
echo '-o ./output/clip2.mkv --language 0:eng clip2.mkv' '--language 0:ger ./ger/clip2.mka' '--language 0:spa ./spa/clip2.mka'
Sehen Sie die langen Abschnitte in einfachen Anführungszeichen? Dadurch wird angezeigt, dass es sich um lange Argumente mit Leerzeichen handelt und nicht um Folgen einzelner Argumente.
Um das Problem zu lösen, verwenden Sie beim Erstellen des Arrays einfach normale Anführungszeichen (also dieselben Anführungszeichen, die Sie verwenden würden, wenn Sie Argumente direkt an den Befehl übergeben). zsh führt standardmäßig keine Worttrennung durch, daher müssen Sie technisch gesehen überhaupt keine Anführungszeichen verwenden, aber ich bevorzuge den mit anderen Shells kompatiblen Anführungsstil und setze daher alle Variablenerweiterungen in Anführungszeichen:
#!/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
Das ergibt dieses Ergebnis mit set -x
:
echo -o ./output/clip2.mkv --language 0:eng ./clip2.mkv --language 0:ger ./ger/clip2.mka --language 0:spa ./spa/clip2.mka