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

持续时间和文件名似乎都进入了值,而键似乎只是输出变量名称。如果我以这种方式声明数组:

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

相关内容