获取关联数组中特定值对应的键

获取关联数组中特定值对应的键

我声明一个关联数组:

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]}相同,除了细绳被视为exact 字符串,而不是模式,即使它包含通配符也是如此。

所以:

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并打印它。

相关内容