Bash: almacenamiento del valor clave en variables declaradas en matriz asociativa

Bash: almacenamiento del valor clave en variables declaradas en matriz asociativa

Estoy intentando crear una matriz asociativa en bash que contenga el nombre de un archivo (un video) y su duración. El código es:

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

Quiero pasar el nombre del archivo y almacenarlo en la variable clave y la duración en la variable valor. En realidad, la duración se consultará a través de ffprobe, pero eso es irrelevante en este punto porque los valores no se pasan correctamente a las variables.

Los resultados son:

$ 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

La duración y el nombre del archivo parecen estar incluidos en el valor, y la clave parece simplemente generar los nombres de las variables. Además, si declaro la matriz de esta manera:

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

aunque elimina la advertencia, todavía genera basura.

Respuesta1

Y la matriz asociativa usa cadenas como índices para recuperar valores. Funciona como una matriz simple en la que se utilizan cadenas en lugar de números enteros para abordar el contenido.

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

Respuesta2

Creo que no había sido capaz de articular mi problema y tal vez debería atribuirlo a unproblema XY.Lo que quería hacer era coleccionarnombres de archivosde archivos mp4 y susduracionesen una matriz asociativa como pares clave-valor, connombres de archivoscomo llaves yduracionescomo valores. Lo estaba abordando completamente de manera incorrecta.

Esta parece ser una solución razonable, donde los nombres de los archivos de las películas se leen y se prueban sus duraciones al mismo tiempo y se almacenan de una sola vez.

Espero que esto ayude a alguien.

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

información relacionada