Bash — сохранение значения ключа в переменных, объявленных в ассоциативном массиве

Bash — сохранение значения ключа в переменных, объявленных в ассоциативном массиве

Я пытаюсь создать ассоциативный массив в bash, содержащий имя файла (видео) и его длительность. Код такой:

#!/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[@]}"

Я хочу передать имя файла и сохранить его в переменной key, а длительность — в переменной value. Длительность на самом деле будет запрошена через ffprobe, но на данном этапе это несущественно, поскольку значения не передаются в переменные правильно.

Результаты таковы:

$ 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

Длительность и имя файла, похоже, попадают в значение, а key, похоже, просто выводит имена переменных. Также, если я объявлю массив таким образом:

declare -A MYMAP=[$filename]=${duration}

хотя это и убирает предупреждение, но все равно выводит мусор.

решение1

И ассоциативный массив использует строки как индексы для извлечения значений. Он работает как обычный массив, где вы используете строки вместо целых чисел для адресации содержимого.

# 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[@]}

решение2

Я думаю, что я не смог четко сформулировать свою проблему, и, возможно, мне следует свести ее кПроблема XY.Я хотел собратьимена файловфайлов mp4 и ихдлительностив ассоциативном массиве как пары ключ-значение, симена файловкак ключи идлительностикак ценности. Я подходил к этому совершенно неправильно.

Это кажется разумным решением, при котором имена файлов фильмов считываются, их длительность проверяется одновременно и сохраняется за один раз.

Надеюсь, это кому-то поможет.

 #!/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

Связанный контент