staging.inyokaproject.org

Variablen bearbeiten und in For-Schleife einsetzen

Status: Ungelöst | Ubuntu-Version: Xubuntu 16.04 (Xenial Xerus)
Antworten |

Fried-rich

Anmeldungsdatum:
2. Mai 2013

Beiträge: 1162

Hallo,

ich beschreibe hier mal mein Ansinnen verkürzt, denke das würde sonst zu unübersichtlich. Ich möchte per Skript aus Matroska-Dateien alle Audiospuren extrahieren lassen, unabhängig davon wieviele Audiospuren es sind und an welche Stelle sie sich befinden (welche ID sie haben). Dazu lasse ich zunächst per

mediainfo "--Inform=Audio;%ID%\n" quelldatei.mkv | grep -v "^$"

die IDs aller Audiotracks der Datei auslesen. Jede ID steht in einer eigenen Zeile und grep löscht die Leerzeile ganz unten. Das könnte aus aussehen:

2
3

Es sollen auch weitere Angaben ausgelesen werden (z. B. die Sprache), aus denen dann der Ausgabename zusammengebastelt wird, das lasse ich jetzt hier aber weg. Der Befehl für die Extrahierung würde bei manueller Eingabe so aussehen (mit mkvextract):

mkvextract quelldatei.mkv tracks 1:German.ac3 2:Englisch.ac3

Ich müsste also die Tracknummern (hier 1: und 2:) durch die vorher ausgelesenen Variablen ersetzen lassen. Dazu habe ich das hier erstellt:

id=$(mediainfo "--Inform=Audio;%ID%\n" quelldatei.mkv | grep -v "^$")
for i in "${id[@]}" ; do
i_mod=$[i-1]
mkvextract quelldatei.mkv tracks $i_mod:German.ac3
done

Die Variable 'i_mod' zieht von der ID 1 ab, da die Zählung bei Mediainfo bei 1 und bei MKVExtract bei o beginnt. Und genau hier liegt das Problem. Es kommt die Fehlermeldung für diese Zeile mit 'i_mod':

3: Syntaxfehler im Ausdruck. (Fehlerverursachendes Zeichen ist »3«).

Wenn ich mit $1 per 'echo' anzeigen lasse kommt

2 3

statt

2
3

Ich denke das ist der Grund wieso die Berechnung nicht geht. Während des For wird aus der Liste mit jeder ID in einer eigenen Zeile eine Liste mit allen Einträgen in einer Zeile mit einem Leerzeichen dazwischen.

Akedia

Anmeldungsdatum:
3. Januar 2018

Beiträge: 93

Versuch es mal ohne Anführungszeichen:

for i in ${id[@]} ; do

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4735

@Akedia: Warum? Was soll das bringen?

@Fried-rich: Kannst Du ein Beispiel zeigen das man nachvollziehen kann? Also ohne das man irgendwas braucht was nur Du kannst/hast? Denn das hier funktioniert bei mir problemlos:

$ id=(1 2)
$ echo "${id[@]}"
1 2
$ for i in "${id[@]}"; do echo $[i-1]; done
0
1 

Edit: Okay, ich bin blind. Natürlich funktioniert das nur wenn id ein Array ist. Was bei meinem Beispiel der Fall ist, aber bei Deinem Code natürlich nicht. Also bei Dir sollte da dann einfach for i in $id; do … stehen. Und ich würde $id nicht in der Einzahl benennen, denn die Variable enthält ja (potentiell) mehr als eine ID. $i dagegen könnte man dann tatsächlich $id nennen, denn genau das ist es ja.

Fried-rich

(Themenstarter)

Anmeldungsdatum:
2. Mai 2013

Beiträge: 1162

Der Tipp von Akedia war aber tatsächlich die Lösung. Mir fällt jetzt nichts ein wie man das allgemeiner halten könnte, außer man nimmt wie du 'id=(1 2)' oder fügt hier einen Zeilenumbruch ein - falls das geht.

Ich hab aber ein anderes Problem, dass sich erst jetzt wo es geht ergeben hat - aber irgendwie logisch ist wenn man das bis zu Ende durchdenkt 😲

Hab jetzt mal auch die Sprache des Streams mit ausgelesen und als Dateiname einfügen lassen. Das sieht jetzt so aus:

id=$(mediainfo "--Inform=Audio;%ID%\n" quelldatei.mkv | grep -v "^$")
for i in ${id[@]} ; do
i_mod=$[i-1]
sprache=$(mediainfo "--Inform=Audio;%Language/String%\n" quelldatei.mkv | grep -v "^$" | head -n $i_mod | tail -n 1)
echo mkvextract quelldatei.mkv tracks $i_mod:$sprache.ac3
done

(Hab hier noch 'echo' vor den Befehl gesetzt, damit ich den Befehl angezeigt bekomme).

Jetzt bekomme ich ja 2 Befehle angezeigt, einmal für die ID 1 mit Sprache 'German' und einmal für die ID 2 mit Sprache 'Englisch'. Das geht grds., ist aber umständlicher. Mir fällt gerade nichts ein wie ich statt

mkvextract quelldatei.mkv tracks 1:German.ac3
mkvextract quelldatei.mkv tracks 2:English.ac3
mkvextract quelldatei.mkv tracks 1:German.ac3 2:Englisch.ac3

bekomme. Das ganze einfach erweitern in

echo mkvextract quelldatei.mkv tracks $i_mod:$sprache.ac3 $i_mod:$sprache.ac3 

nützt ja nichts, da fügt er ja 2x die gleiche ID und die gleiche Sprache ein.

Ich dachte daran in der For-Schleife in zusätzliche Variablen die Werte für jede ID und für jede Sprache (also z. B. $id1 + $sprache1 ; $id2 + $sprache2 ; usw.) erstellen zu lassen und diese dann unter der For-Schleife einfügen zu lassen:

mkvextract quelldatei.mkv tracks $id1:$sprache1.ac3 $id2:$sprache2.ac3 ... $id''n'':$sprache''n''.ac3

Dazu müsste man aber wissen wieviel Variable es überhaupt zu erstellen gilt. Ich bin grad ganz gediegen überfordert.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4735

@Fried-rich: Der Tipp von Akedia war nicht die Lösung. Das funktioniert zwar, zeigt aber gleichzeitig, dass nicht verstanden wurde was da passiert. Genau wie der Name jeden Arrays für das erste Element steht, kann man auch jede ”skalare” Variable als „alle Elemente des Arrays mit dem Namen“ ausdrücken, was aber überhaupt gar keinen Sinn macht. $id und ${id[@]} ist in dem Fall immer das gleiche, nur das man bei ${id[@]} beim lesen denkt es würde sich bei $id um ein Array handeln. Was es aber eben nicht ist. Darum sollte man es auch nicht so schreiben.

Dein jetziges Problem könnte man dadurch lösen, dass man die Argumente für mkvextract in der Schleife in einer Variablen sammelt (vielleicht auch tatsächlich mal in einem Array), und dann damit nach der Schleife einmal den Aufruf durchführt.

Fried-rich

(Themenstarter)

Anmeldungsdatum:
2. Mai 2013

Beiträge: 1162

Marc_BlackJack_Rintsch schrieb:

Dein jetziges Problem könnte man dadurch lösen, dass man die Argumente für mkvextract in der Schleife in einer Variablen sammelt (vielleicht auch tatsächlich mal in einem Array), und dann damit nach der Schleife einmal den Aufruf durchführt.

Sowas in der Art dachte ich mir, nur hab ich gerade keine Ahnung wie. Ersetze ich den MKVExtract-Befehl durch z. B.

var=z1=$i_mod:$sprache.ac3

bekomme ich sowas

1:German.ac3
2:Englisch.ac3

Wenn man aus diesem zweizeiligen Variableninhalt einen einzeiligen macht mit einem Leerzeichen dazwischen, hätte ich was ich brauche. Nur komm ich da nicht weiter. Vielleicht geht das auch eleganter.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4735

@Fried-rich: Bei dem was Du da zeigst bekommst Du keinen zweizeiligen Inhalt in die Variable. Du musst halt mit einer leeren Variable anfangen und da in jedem Schleifendurchlauf die Werte anhängen. Oder mit einem leeren Array und da in jedem Schleifendurchlauf die zusätzlichen Argumente anhängen.

frostschutz

Avatar von frostschutz

Anmeldungsdatum:
18. November 2010

Beiträge: 7795

Setz es doch direkt in den Format String von mediainfo.

echo mkvextract datei.mkv tracks $(mediainfo "--Inform=Audio;%ID%:%ID%_%Language%.%Codec% " datei.mkv)

ID mit in den Filenamen weils manchmal ja mehr als einen Track in einer Sprache gibt. Dateiname könnte da auch noch mit rein...

Nur Leerzeichen u.ä. dürfen bei dem Ansatz nicht mit

Antworten |