在bash

时间:2017-03-20 06:26:35

标签: bash loops multidimensional-array associative-array

我想在bash中创建一个嵌套关联数组并在循环中填充它。下面是示例代码,它应该打印所有文件名以及当前目录中该文件的相应Last Modification Time。

declare -A file_map
for file in *
do
    declare -A file_attr
    uuid=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)
    file_attr['name']="$file"
    file_attr['mod_date']=$(stat -c %y "$file")
    file_map["$uuid"]=file_attr
done


for key in "${!file_map[@]}"
do
    echo $(eval echo \${${file_map[$key]}['name']}) "->" $(eval echo \${${file_map[$key]}['mod_date']})
done

但它只打印目录中单个文件的信息。

输出结果如下:

test.sh -> 2017-03-10 18:46:52.832356165 +0530
test.sh -> 2017-03-10 18:46:52.832356165 +0530
test.sh -> 2017-03-10 18:46:52.832356165 +0530
test.sh -> 2017-03-10 18:46:52.832356165 +0530

它应该是test.sh和其他3个不同的文件。

似乎declare -A file_attr没有创建任何新的关联数组,因此先前的值会被覆盖。任何肝脏?

1 个答案:

答案 0 :(得分:1)

您需要在每次循环迭代中创建 distinct global 数组,并将其名称存储在“outer”数组中。您还需要declare来分配动态生成的数组。

declare -A file_map
for file in *
do
    declare -A file_attr$((i++))
    # Consider using something like uuidgen instead
    # uuid=$(uuidgen)
    uuid=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)
    declare -A "file_attr$i[name]=$file"
    declare -A "file_attr$i[mod_date]=$(stat -c %y "$file")"
    file_map[$uuid]="file_attr$i"
done

Use indirect variable expansion, not `eval`, to access the elements.

for uuid in "${!file_map[@]}"
do
    arr=${file_map[$uuid]}
    file_map_name=$arr[name]
    file_map_date=$arr[mod_date]
    echo "$uuid: ${!file_map_name} -> ${!file_map_date}"
done