我看到了在Shell脚本中实现关联数组的技巧。例如print array["apples"]
,可以编写为echo \$array$key
key = apples。
但是,没有提到如何生成用于遍历数组的密钥。我能想到的唯一方法是将键存储在以空格分隔的变量中,以便可以使用for循环遍历数组。
因此,还有其他方法可以存储密钥以供以后使用吗?
我看到了在Shell脚本中实现关联数组的技巧。例如print array["apples"]
,可以编写为echo \$array$key
key = apples。
但是,没有提到如何生成用于遍历数组的密钥。我能想到的唯一方法是将键存储在以空格分隔的变量中,以便可以使用for循环遍历数组。
因此,还有其他方法可以存储密钥以供以后使用吗?
Answers:
一些现代的shell提供了关联数组:ksh93,bash≥4,zsh。在ksh93和bash中,如果a
是一个关联数组,则"${!a[@]}"
是其键的数组:
for k in "${!a[@]}"; do
echo "$k -> ${a[$k]}"
done
在zsh中,该语法仅在ksh仿真模式下有效。否则,您必须使用zsh的本机语法:
for k in "${(@k)a}"; do
echo "$k -> $a[$k]"
done
${(k)a}
如果a
没有空键,也可以使用。
在zsh中,您还可以同时循环k
遍历ey和alues v
:
for k v ("${(@kv)a}") echo "$k -> $v"
在没有它们的shell中模拟关联数组需要做很多工作。如果需要关联数组,可能是时候引入更大的工具了,例如ksh93或Perl。
如果仅在POSIX外壳中确实需要关联数组,则当键被限制为仅包含字符0-9A-Z_a-z
(ASCII数字,字母和下划线)时,这是一种模拟它们的方法。在这种假设下,键可以用作变量名的一部分。下面的函数作用于以命名前缀“ stem”标识的数组,该前缀不得包含两个连续的下划线。
## ainit STEM
## Declare an empty associative array named STEM.
ainit () {
eval "__aa__${1}=' '"
}
## akeys STEM
## List the keys in the associatve array named STEM.
akeys () {
eval "echo \"\$__aa__${1}\""
}
## aget STEM KEY VAR
## Set VAR to the value of KEY in the associative array named STEM.
## If KEY is not present, unset VAR.
aget () {
eval "unset $3
case \$__aa__${1} in
*\" $2 \"*) $3=\$__aa__${1}__$2;;
esac"
}
## aset STEM KEY VALUE
## Set KEY to VALUE in the associative array named STEM.
aset () {
eval "__aa__${1}__${2}=\$3
case \$__aa__${1} in
*\" $2 \"*) :;;
*) __aa__${1}=\"\${__aa__${1}}$2 \";;
esac"
}
## aunset STEM KEY
## Remove KEY from the associative array named STEM.
aunset () {
eval "unset __aa__${1}__${2}
case \$__aa__${1} in
*\" $2 \"*) __aa__${1}=\"\${__aa__${1}%%* $2 } \${__aa__${1}#* $2 }\";;
esac"
}
(警告,未经测试的代码。未提供语法无效的词干和键的错误检测。)
我不确定store的意思,但是可以使用以下${!array[@]}
语法来遍历键:
$ typeset -A foo=([key1]=bar [key2]=baz);
$ echo "${!foo[@]}"
key2 key1
因此,要迭代:
$ for key in "${!foo[@]}"; do echo "$key : ${foo[$key]}"; done
key2 : baz
key1 : bar
我在这里找到了一个不错的简短教程。
(bash version 4 only)
这是要注意的重要事项。传统上,bash
数组仅是数字。
typeset
而不是declare
。那将使它们在bash 4和ksh93之间可移植,后者首先实现了shell关联数组。
当键限制为[0-9A-Za-z_]
(数字,字母,下划线)时,这并不难。
诀窍不是存储到array [ $ key ] 而是存储到变量array_ $ key。
组:
eval "array_$key='$value'"
得到:
value=`eval echo '$'array_$key`
注意:值不能包含'
(单引号)。
这在bash中起作用
cert="first"
web="second"
declare -A assoc_array=(["cert"]="${cert}" ["web"]="${web}")
echo "first is" ${assoc_array[cert]}
echo "second is" ${assoc_array[web]}
要么
#loop
for i in "${assoc_array[@]}"
do
echo "$i"
done
无需使用eval afaik