我试图在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
我觉得我错过了一些简单的事情,但寻找答案并不能解决任何问题。任何帮助将不胜感激。
答案 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条目当前不像人们想要的那样清晰。所以这是我的简短摘要:
declare
(以及其他相关内置文件,包括export
,local
和typeset
)评估其参数。因此,您可以在declare
语句中构建变量名称。
由于declare
也可用于赋值(只要您使用相同的声明),您可以在声明语句中建立索引变量名。
如果您使用的是bash4.3或更高版本,则可以使用namerefs(typeset -n
或declare -n
)来模拟数组值。这真的是你可以从bash函数返回一个数组的唯一方法,但它仍然有点尴尬,因为它要求函数的调用者提供一个带有数组名称的参数;此外,它不是完全健壮的,因为名称将在函数的范围内使用,因此它可能被局部变量遮蔽。需要注意。
使用变量间接可能没有其他充分的理由。如果您发现自己需要它,请考虑是否可以采用不同的方式构建程序。您可以使用字符串连接折叠关联键。例如:
my_array[${place}:${feature}]
只要${place}
没有值包含冒号,就会工作(当然,你可以使用不同的字符而不是冒号)。
注意按键。如果数组被声明为关联的,则通常或多或少地评估键,但如果它是普通的索引数组,则将键计算为算术表达式。结果是
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