シェルスクリプトで連想配列を実装するためのトリックを見ました。たとえば、print array["apples"]
はecho \$array$key
としてスクリプト化できます。ここで、key = applesです。
ただし、配列を反復処理するためのキーを生成する方法については言及されていません。スペースで区切られた変数にキーを格納して、forループを使用して配列を反復できるようにすることしか考えられませんでした。
それで、後で使用するためにキーを格納する他の方法はありますか?
最近のシェルの中には、連想配列を提供するものがあります:ksh93、bash≥4、zsh。 ksh93およびbashでは、a
が連想配列の場合、_"${!a[@]}"
_はそのキーの配列です。
_for k in "${!a[@]}"; do
echo "$k -> ${a[$k]}"
done
_
Zshでは、その構文はkshエミュレーションモードでのみ機能します。それ以外の場合は、zshのネイティブ構文を使用する必要があります。
_for k in "${(@k)a}"; do
echo "$k -> $a[$k]"
done
_
${(k)a}
は、a
に空のキーがない場合にも機能します。
Zshでは、k
eysとv
aluesの両方を同時にループすることもできます。
_for k v ("${(@kv)a}") echo "$k -> $v"
_
連想配列を持たないシェルで連想配列をエミュレートすることは、はるかに多くの作業です。連想配列が必要な場合は、おそらくksh93やPerlなどのより大きなツールを導入するときです。
単なるPOSIXシェルで連想配列が必要な場合、キーが文字_0-9A-Z_a-z
_(ASCIIの数字、文字、およびアンダースコア)のみを含むように制限されている場合に、それらをシミュレートする方法を以下に示します。この前提の下で、キーは変数名の一部として使用できます。以下の関数は、2つの連続したアンダースコアを含んではならない「stem」という名前の接頭辞で識別される配列に作用します。
_## 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"
}
_
(警告、テストされていないコード。構文的に無効なステムおよびキーのエラー検出は提供されていません。)
ストアの意味がわかりませんが、${!array[@]}
構文を使用してキーを反復できます。
$ typeset -A foo=([key1]=bar [key2]=baz);
$ echo "${!foo[@]}"
key2 key1
したがって、反復するには:
$ for key in "${!foo[@]}"; do echo "$key : ${foo[$key]}"; done
key2 : baz
key1 : bar
私はこれについてニースの短いチュートリアルを見つけました here 。
以下のコメントで指摘されているように、連想配列はbash
バージョン4で追加されました。この件に関するLinuxジャーナルの記事については here を参照してください。
キーが[0-9A-Za-z_]
(数字、文字、アンダースコア)に制限されている場合はそれほど難しくありません。
コツは、配列に保存する代わりに[$ key]、変数に保存するarray_$ key。
セットする:
eval "array_$key='$value'"
取得する:
value=`eval echo '$'array_$key`
注:値に'
(一重引用符)を含めることはできません。