如何在Bash中迭代关联数组


351

基于Bash脚本中的关联数组,我需要对其进行迭代以获取键和值。

#!/bin/bash

declare -A array
array[foo]=bar
array[bar]=foo

我实际上不了解在使用for-in循环时如何获取密钥。


14
$ clarify -A array =([foo] = bar [bar] = foo)#一次全部初始化
anisbet 2014年

3
对于一小部分键值,您可以考虑以下for i in a,b c_s,d ; do KEY=${i%,*}; VAL=${i#*,}; echo $KEY" XX "$VAL; done
数学2014年

Answers:


581

可以使用感叹号来访问键:${!array[@]},使用来访问${array[@]}

您可以像这样遍历键/值对:

for i in "${!array[@]}"
do
  echo "key  : $i"
  echo "value: ${array[$i]}"
done

注意for语句中变量周围的引号(加上@代替的使用*)。如果任何键包含空格,则这是必需的。

其他答案的困惑来自于这样一个事实,即您的问题的键值都包含“ foo”和“ bar” 。


3
现在,如果将所有键分配给一个数组,则为:array=(${!hash[@]})
Michael-O

12
@ Michael-O:您需要引用参数扩展名以保护可能具有空格的键:array=("${!hash[@]}")
已暂停,直到另行通知。

@DennisWilliamson,非常感谢。我没有这个想法。
Michael-O

我们如何使用函数参数编号而不是变量?例如for i in "${!$1[@]}"
pkaramol '18

2
@pkaramol:从Bash 4.3开始,您可以使用namerefs。范例:declare -A aa; aa['A']=a1; aa['B']=b2; aa['C']=c3; foo () { declare -n assoc=$1; for key in "${!assoc[@]}"; do echo "Key: $key; Value: ${assoc[$key]}"; done; }; foo aa。请参阅BashFAQ / 006了解一些重要信息。
暂停,直到另行通知。

42

您可以使用以下命令访问密钥${!array[@]}

bash-4.0$ echo "${!array[@]}"
foo bar

然后,轻松遍历键/值对:

for i in "${!array[@]}"
do
  echo "key :" $i
  echo "value:" ${array[$i]}
done

1
我有“!” -甚至没有注意到,什么都没有,对不起.. :)
pex

8

使用此高阶函数来防止厄运金字塔

foreach(){ 
  arr="$(declare -p $1)" ; eval "declare -A f="${arr#*=}; 
  for i in ${!f[@]}; do $2 "$i" "${f[$i]}"; done
}

例:

$ bar(){ echo "$1 -> $2"; }
$ declare -A foo["flap"]="three four" foo["flop"]="one two"
$ foreach foo bar
flap -> three four
flop -> one two

1
我不确定这如何适用?厄运金字塔不是纯粹的美学问题,真的仅适用于面向对象的语言吗?
Alexej Magura

1
你能解释一下吗?foreach函数有点棘手。我不明白
巴林特西盖蒂

-1
declare -a arr
echo "-------------------------------------"
echo "Here another example with arr numeric"
echo "-------------------------------------"
arr=( 10 200 3000 40000 500000 60 700 8000 90000 100000 )

echo -e "\n Elements in arr are:\n ${arr[0]} \n ${arr[1]} \n ${arr[2]} \n ${arr[3]} \n ${arr[4]} \n ${arr[5]} \n ${arr[6]} \n ${arr[7]} \n ${arr[8]} \n ${arr[9]}"

echo -e " \n Total elements in arr are : ${arr[*]} \n"

echo -e " \n Total lenght of arr is : ${#arr[@]} \n"

for (( i=0; i<10; i++ ))
do      echo "The value in position $i for arr is [ ${arr[i]} ]"
done

for (( j=0; j<10; j++ ))
do      echo "The length in element $j is ${#arr[j]}"
done

for z in "${!arr[@]}"
do      echo "The key ID is $z"
done
~
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.