
Ich versuche, in Bash ein assoziatives Array zu erstellen, das den Namen einer Datei (eines Videos) und ihre Dauer enthält. Der Code lautet:
#!/bin/sh
shopt -s nullglob
movie=(*.mp4)
declare -A MYMAP[$filename]=${duration}
total=${#movie[*]}
for (( i=0; i<=$(( $total -1 )); i++ ))
do
MYMAP[duration]=10
MYMAP[filename]=${movie[i]}
echo "${MYMAP[@]}"
echo "${!MYMAP[@]}"
done
echo "${#MYMAP[@]}"
Ich möchte den Dateinamen übergeben und ihn in der Schlüsselvariable und die Dauer in der Wertvariable speichern. Die Dauer wird eigentlich über ffprobe abgefragt, aber das ist an dieser Stelle unerheblich, da die Werte nicht korrekt an die Variablen übergeben werden.
Die Ergebnisse sind:
$ sh test2.sh
test2.sh: line 6: MYMAP[]: bad array subscript
10 File_01.mp4
duration filename
10 File_02.mp4
duration filename
10 File_03.mp4
duration filename
10 File_04.mp4
duration filename
10 File_05.mp4
duration filename
2
Sowohl die Dauer als auch der Dateiname scheinen in den Wert einzufließen, und der Schlüssel scheint nur die Variablennamen auszugeben. Auch wenn ich das Array folgendermaßen deklariere:
declare -A MYMAP=[$filename]=${duration}
obwohl die Warnung entfernt wird, wird immer noch Müll ausgegeben.
Antwort1
Und assoziative Arrays verwenden Zeichenfolgen als Indizes, um Werte abzurufen. Es funktioniert wie ein einfaches Array, bei dem Sie Zeichenfolgen anstelle von Ganzzahlen verwenden, um den Inhalt zu adressieren.
# Declare the array
declare -A durations
# Two movies
sw1="ANewHope.mp4"
sw2="EmpireStrikesBack.mp4"
# Store values
durations[$sw1]=3600
durations[$sw2]=7200
# Retrieve values
echo ${durations[$sw1]}
echo ${durations[$sw2]}
# The movies
echo ${!durations[@]}
# The durations
echo ${durations[@]}
Antwort2
Ich glaube, ich war nicht in der Lage, mein Problem klar auszudrücken, und vielleicht sollte ich es auf eineXY-Problem.Ich wollte sammelnDateinamenvon mp4-Dateien und derenDauerin einem assoziativen Array als Schlüssel-Wert-Paare, mitDateinamenals Schlüssel undDauerals Werte. Ich bin völlig falsch an die Sache herangegangen.
Dies scheint eine sinnvolle Lösung zu sein, bei der die Dateinamen der Filme eingelesen, ihre Dauer gleichzeitig abgefragt und in einem Durchgang gespeichert werden.
Hoffe, das hilft jemandem.
#!/bin/sh
shopt -s nullglob
declare -A DURATIONARR
while IFS= read -r movie
do
DURATIONARR[$movie]=$(ffprobe "$movie" 2>&1 | grep Duration | sed -e 's/^[[:space:]]*//g' | \
awk '{print $2}' | tr -d ,)
done< <(find . -name "*.mp4" -exec basename {} \;)
printf "%s\n" "${!DURATIONARR[@]}" "${DURATIONARR[@]}" | pr -2t
unset DURATIONARR