我声明一个关联数组:
declare -A array=([a]=blue [b]=red [c]=yellow)
现在我可以做:
echo ${array[@]} --> blue red yellow
或者
echo ${array[b]} --> red
或者
echo ${!array[@]} --> a b c
现在我只想知道与red
值关联的键。有没有办法只检测单个密钥?
答案1
假设您想要获取与特定值相对应的键列表,并且希望将此列表存储在数组中:
#!/bin/bash
declare -A hash
hash=(
[k1]="hello world"
[k2]="hello there"
[k3]="hello world"
[k4]=bumblebees
)
string="hello world"
keys=()
for key in "${!hash[@]}"; do
if [[ ${hash[$key]} == "$string" ]]; then
keys+=( "$key" )
fi
done
printf 'Keys with value "%s":\n' "$string"
printf '\t%s\n' "${keys[@]}"
这将遍历键列表,并根据我们要查找的字符串测试每个键对应的值。如果存在匹配,我们将密钥存储在keys
数组中。
最后,输出找到的密钥。
该脚本的输出将是
Keys with value "hello world":
k1
k3
答案2
shell zsh
(请注意,zsh
几十年前就有关联数组支持bash
)具有以下运算符:
${hash[(R)pattern]}
扩展到价值观与模式匹配的。${(k)hash[(R)pattern]}
扩展到相应值与模式匹配的键。${(k)hash[(Re)string]}
相同,除了细绳被视为e
xact 字符串,而不是模式,即使它包含通配符也是如此。
所以:
print -r -- ${(k)array[(Re)red]}
将打印非空值为 的键red
。
要包含空键,请使用:
$ typeset -A array
$ array=(a blue b red c yellow '' red)
$ printf '<%s>\n' "${(@k)array[(Re)red]}"
<>
<b>
答案3
这并不漂亮,但你可以这样做:
for k in "${!array[@]}"; do
[[ ${array[$k]} == red ]] && printf '%s\n' "$k"
done
这将循环遍历数组的索引并检查每个索引的值是否为red
,如果是,则打印索引。
或者,也不太漂亮,你可以使用sed
:
declare -p array | sed -n 's/.*\[\(.*\)\]="red".*/\1/p'
这将打印声明的数组,找到值的索引red
并打印它。