Egg*_*ead 11 shell-script associative-array
我看到了在 shell 脚本中实现关联数组的技巧。例如,print array["apples"]
可以将脚本编写为echo \$array$key
where key=apples。
但是,没有提到如何生成键来迭代数组。我能想到的唯一方法是将键存储在一个由空格分隔的变量中,这样我就可以使用 for 循环来遍历数组。
那么,是否有其他方法可以存储密钥以备后用?
Gil*_*il' 20
一些现代 shell 提供关联数组:ksh93、bash ?4、zsh。在 ksh93 和 bash 中,如果a
是关联数组,则"${!a[@]}"
是其键的数组:
for k in "${!a[@]}"; do
echo "$k -> ${a[$k]}"
done
Run Code Online (Sandbox Code Playgroud)
在 zsh 中,该语法仅适用于 ksh 仿真模式。否则你必须使用 zsh 的原生语法:
for k in "${(@k)a}"; do
echo "$k -> $a[$k]"
done
Run Code Online (Sandbox Code Playgroud)
${(k)a}
如果a
没有空键也可以使用。
在 zsh 中,您还可以同时在k
eys 和 alues上循环v
:
for k v ("${(@kv)a}") echo "$k -> $v"
Run Code Online (Sandbox Code Playgroud)
在没有关联数组的 shell 中模拟关联数组需要做更多的工作。如果您需要关联数组,可能是时候引入更大的工具了,例如 ksh93 或 Perl。
如果您确实需要在单纯的 POSIX shell 中使用关联数组,这里有一种模拟它们的方法,当键被限制为仅包含字符0-9A-Z_a-z
(ASCII 数字、字母和下划线)时。在这种假设下,键可以用作变量名的一部分。下面的函数作用于一个由命名前缀“词干”标识的数组,它不能包含两个连续的下划线。
## 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"
}
Run Code Online (Sandbox Code Playgroud)
(警告,未经测试的代码。不提供语法无效词干和键的错误检测。)
我不确定您所说的 store 是什么意思,但您可以使用以下${!array[@]}
语法迭代键:
$ typeset -A foo=([key1]=bar [key2]=baz);
$ echo "${!foo[@]}"
key2 key1
Run Code Online (Sandbox Code Playgroud)
所以,要迭代:
$ for key in "${!foo[@]}"; do echo "$key : ${foo[$key]}"; done
key2 : baz
key1 : bar
Run Code Online (Sandbox Code Playgroud)
我在这里找到了一个不错的简短教程。
正如在下面的评论中指出的那样,在bash
第 4 版中添加了关联数组。 有关该主题的 Linux 期刊文章,请参见此处。