連想配列を宣言します。
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
参照)には、次の演算子があります。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
印刷されます。