bash中的关联数组名称数组

时间:2015-02-12 18:53:30

标签: arrays linux bash shell

我试图在bash中管理一个带有数组的关联数组列表,而我似乎无法找到不对的内容。

我想做的事情:

array=(a b c d)

for i in ${array[@]}; do
    declare -A $i
done

a[key]=avalue
b[key]=bvalue
c[key]=cvalue
d[key]=dvalue

这一切似乎都运行正常,因为我可以通过引用${a[key]}来手动返回值。

然而,当我尝试使用array变量进行迭代时,它并没有真正给出我期望的结果。

for index in ${array[@]}; do
  echo ${index[key]}
done

返回的方式就像我要运行一样

for index in ${array[@]}; do
  echo $index
done

我觉得我错过了一些简单的事情,但寻找答案并不能解决任何问题。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:7)

这是一个使用 shell间接的解决方案。这适用于支持关联数组的任何bash。间接必须包含整个引用,包括下标,这有点尴尬。

for index in "${array[@]}"; do
  indexkey=${index}[key]
  echo "${!indexkey}"
done

使用现代bash(至少v4.3),您可以使用 nameref声明来创建别名。这样更方便,因为您可以使用具有相同别名的不同键:

for index in "${array[@]}"; do
  declare -n subarray=$index
  echo "${subarray[key]}"
done

接近解释的东西。

正如Etan Reisner在评论中指出的那样,这个问题在Bash FAQ entry中得到了一定程度的处理。但是,在我写的那天,该FAQ条目包括免责声明"检修此页面将需要一些时间和工作",并且当前FAQ条目当前不像人们想要的那样清晰。所以这是我的简短摘要:

  1. declare(以及其他相关内置文件,包括exportlocaltypeset)评估其参数。因此,您可以在declare语句中构建变量名称。

  2. 由于declare也可用于赋值(只要您使用相同的声明),您可以在声明语句中建立索引变量名。

  3. 如果您使用的是bash4.3或更高版本,则可以使用namerefs(typeset -ndeclare -n)来模拟数组值。这真的是你可以从bash函数返回一个数组的唯一方法,但它仍然有点尴尬,因为它要求函数的调用者提供一个带有数组名称的参数;此外,它不是完全健壮的,因为名称将在函数的范围内使用,因此它可能被局部变量遮蔽。需要注意。

  4. 使用变量间接可能没有其他充分的理由。如果您发现自己需要它,请考虑是否可以采用不同的方式构建程序。您可以使用字符串连接折叠关联键。例如:

    my_array[${place}:${feature}]
    
    只要${place}没有值包含冒号,

    就会工作(当然,你可以使用不同的字符而不是冒号)。

  5. 注意按键。如果数组被声明为关联的,则通常或多或少地评估键,但如果它是普通的索引数组,则将键计算为算术表达式。结果是

    declare -A assoc
    declare -a indexed
    key=42
    # This assigns the element whose key is "key"
    assoc[key]=foo
    # This assigns the element whose key is 42
    indexed[key]=foo
    # If $key had not been defined, the above would have assigned
    # the element whose key was 0, without an error message