
Estou tentando criar um array associativo no bash contendo o nome de um arquivo (um vídeo) e sua duração. O código é:
#!/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[@]}"
Quero passar o nome do arquivo e armazená-lo na variável chave e a duração na variável valor. A duração será realmente consultada através do ffprobe, mas isso é irrelevante neste momento porque os valores não estão sendo passados para as variáveis corretamente.
Os resultados são:
$ 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
A duração e o nome do arquivo parecem estar entrando no valor, e a chave parece estar apenas gerando os nomes das variáveis. Além disso, se eu declarar o array desta forma:
declare -A MYMAP=[$filename]=${duration}
embora remova o aviso, ainda gera lixo.
Responder1
E o array associativo usa strings como índices para recuperar valores. Funciona como um array simples onde você usa strings em vez de números inteiros para endereçar o conteúdo.
# 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[@]}
Responder2
Penso que não fui capaz de articular o meu problema, e talvez devesse atribuí-lo a umProblema XY.O que eu queria fazer era coletarnomes de arquivosde arquivos mp4 e seusduraçõesem uma matriz associativa como pares de valores-chave, comnomes de arquivoscomo chaves eduraçõescomo valores. Eu estava abordando isso de maneira completamente errada.
Esta parece ser uma solução razoável, onde os nomes dos arquivos dos filmes são lidos e suas durações investigadas ao mesmo tempo e armazenadas de uma só vez.
Espero que isso ajude alguém.
#!/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