如何在 Bash 中迭代关联数组
Posted
技术标签:
【中文标题】如何在 Bash 中迭代关联数组【英文标题】:How to iterate over associative arrays in Bash 【发布时间】:2011-03-07 23:05:12 【问题描述】:基于 Bash 脚本中的关联数组,我需要对其进行迭代以获取键和值。
#!/bin/bash
declare -A array
array[foo]=bar
array[bar]=foo
我实际上不明白如何在使用 for-in 循环时获取密钥。
【问题讨论】:
$ declare -A array=( [foo]=bar [bar]=foo ) # 一次性初始化 对于一小部分键值,您可以考虑:for i in a,b c_s,d ; do KEY=$i%,*; VAL=$i#*,; echo $KEY" XX "$VAL; done
【参考方案1】:
欢迎使用输入关联数组2.0!
clear
echo "Welcome to input associative array 2.0! (Spaces in keys and values now supported)"
unset array
declare -A array
read -p 'Enter number for array size: ' num
for (( i=0; i < num; i++ ))
do
echo -n "(pair $(( $i+1 )))"
read -p ' Enter key: ' k
read -p ' Enter value: ' v
echo " "
array[$k]=$v
done
echo " "
echo "The keys are: " $!array[@]
echo "The values are: " $array[@]
echo " "
echo "Key <-> Value"
echo "-------------"
for i in "$!array[@]"; do echo $i "<->" $array[$i]; done
echo " "
echo "Thanks for using input associative array 2.0!"
输出:
Welcome to input associative array 2.0! (Spaces in keys and values now supported)
Enter number for array size: 4
(pair 1) Enter key: Key Number 1
Enter value: Value#1
(pair 2) Enter key: Key Two
Enter value: Value2
(pair 3) Enter key: Key3
Enter value: Val3
(pair 4) Enter key: Key4
Enter value: Value4
The keys are: Key4 Key3 Key Number 1 Key Two
The values are: Value4 Val3 Value#1 Value2
Key <-> Value
-------------
Key4 <-> Value4
Key3 <-> Val3
Key Number 1 <-> Value#1
Key Two <-> Value2
Thanks for using input associative array 2.0!
输入关联数组1.0
(不支持包含空格的键和值)
clear
echo "Welcome to input associative array! (written by mO extraordinaire!)"
unset array
declare -A array
read -p 'Enter number for array size: ' num
for (( i=0; i < num; i++ ))
do
read -p 'Enter key and value separated by a space: ' k v
array[$k]=$v
done
echo " "
echo "The keys are: " $!array[@]
echo "The values are: " $array[@]
echo " "
echo "Key <-> Value"
echo "-------------"
for i in $!array[@]; do echo $i "<->" $array[$i]; done
echo " "
echo "Thanks for using input associative array!"
输出:
Welcome to input associative array! (written by mO extraordinaire!)
Enter number for array size: 10
Enter key and value separated by a space: a1 10
Enter key and value separated by a space: b2 20
Enter key and value separated by a space: c3 30
Enter key and value separated by a space: d4 40
Enter key and value separated by a space: e5 50
Enter key and value separated by a space: f6 60
Enter key and value separated by a space: g7 70
Enter key and value separated by a space: h8 80
Enter key and value separated by a space: i9 90
Enter key and value separated by a space: j10 100
The keys are: h8 a1 j10 g7 f6 e5 d4 c3 i9 b2
The values are: 80 10 100 70 60 50 40 30 90 20
Key <-> Value
-------------
h8 <-> 80
a1 <-> 10
j10 <-> 100
g7 <-> 70
f6 <-> 60
e5 <-> 50
d4 <-> 40
c3 <-> 30
i9 <-> 90
b2 <-> 20
Thanks for using input associative array!
【讨论】:
【参考方案2】: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
~
【讨论】:
【参考方案3】:使用这个高阶函数来防止pyramid of doom
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
【讨论】:
我不确定这如何适用?末日金字塔不是纯粹的美学问题,真的只适用于面向对象的语言吗? 你能解释一下吗? foreach 函数有点棘手。我不明白。【参考方案4】:您可以使用$!array[@]
访问密钥:
bash-4.0$ echo "$!array[@]"
foo bar
然后,迭代键/值对很容易:
for i in "$!array[@]"
do
echo "key :" $i
echo "value:" $array[$i]
done
【讨论】:
我有“!” - 甚至没有注意到,没有,抱歉.. :)【参考方案5】:使用感叹号访问键:$!array[@]
,使用$array[@]
访问值。
您可以像这样迭代键/值对:
for i in "$!array[@]"
do
echo "key : $i"
echo "value: $array[$i]"
done
注意在for
语句中使用引号引起的变量(加上使用@
而不是*
)。如果任何键包含空格,这是必要的。
另一个答案的困惑来自于您的问题包括键和值的“foo”和“bar”。
【讨论】:
现在如果将所有键分配给一个数组:array=($!hash[@])
@Michael-O:你需要引用参数扩展来保护可能有空格的键:array=("$!hash[@]")
@DennisWilliamson,非常感谢。我没有这个想法。
我们如何使用函数参数编号而不是变量?例如for i in "$!$1[@]"
?
@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 了解一些重要信息。以上是关于如何在 Bash 中迭代关联数组的主要内容,如果未能解决你的问题,请参考以下文章