連想配列の特定の値に対応するキーを取得します。

連想配列の特定の値に対応するキーを取得します。

連想配列を宣言します。

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

シェル(連想配列のサポートは数十年前に存在していたことをzsh参照)には、次の演算子があります。zshbash

  • ${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印刷されます。

関連情報