3つの連想配列があります。
declare -A start_obj end_obj gopath
start_obj['one']="start-obj-one"
start_obj['two']="start-obj-two"
end_obj['one']="end-obj-one"
end_obj['two']="end-obj-two"
gopath['start']="/path/to/start"
gopath['end']="/path/to/end"
配列のキーから配列のキーと値を取得したいと思いますstart_obj
。コードは次のとおりです。end_obj
gopath
for t in "${!gopath[@]}"
do
current=$t"_obj"[@]
cd ${gopath[$t]}
for k in ${!current}
do
printf "[$t]key is : $k ; value is : ${current[$k]}\n"
done
done
ただし、このコードの実行結果は次のとおりです。
[start]key is : start-obj-one ; value is : start_obj[@]
[start]key is : start-obj-two ; value is : start_obj[@]
[end]key is : end-obj-one ; value is : end_obj[@]
[end]key is : end-obj-two ; value is : end_obj[@]
私が望む結果は次のとおりです。
[start]key is : one ; value is : start-obj-one
[start]key is : two ; value is : start-obj-two
[end]key is : one ; value is : end-obj-one
[end]key is : two ; value is : end-obj-two
それでは、必要な結果を得るためにコードをどのように修正する必要がありますか?
ベストアンサー1
bash
バージョン4.3以降では、nameref変数を使用できます。
for t in "${!gopath[@]}"; do
(
typeset -n current="${t}_obj"
cd -P -- "${gopath[$t]}" || exit
for k in "${!current[@]}"
do
printf '%s\n' "[$t]key is: $k; value is: ${current[$k]}"
done
)
done
以前のバージョンでは、以下を使用する必要がありますeval
。
for t in "${!gopath[@]}"; do
(
cd -P -- "${gopath[$t]}" || exit
eval '
for k in "${!'"$t"'_obj[@]}"
do
printf "%s\n" "[$t]key is: $k; value is: ${'"$t"'_obj[$k]}"
done
'
)
done
bash
変数間接演算子があります:${!varname}
演算子とは関係ありませんが${!hash[@]}
(実際にはksh93の反対側に近いです${!varname}
)、演算子と組み合わせることはできません${!hash[@]}
(varname=hash; for key in "${!!varname[@]}"...
機能しません)。ここで使用できる可変間接演算子があり、より長い間連想配列をサポートしたシェルの場合はzsh
(${(P)varname}
)を使用して確認できます。これにより、キーと値を同時に繰り返すこともできます。
typeset -A start_obj end_obj gopath
start_obj=(
one start-obj-one
two start-obj-two
)
end_obj=(
one end-obj-one
two end-obj-two
)
gopath=(
start /path/to/start
end /path/to/end
)
for t dir ("${(kv@)gopath}") (
cd -P -- "$dir" || exit
current=${t}_obj
for key value ("${(kvP@)current}")
printf '%s\n' "[$t]key is: $key; value is: $value}"
)
とにかく、 bash
and zsh
(そしてksh93
連想配列を導入してコピーしようとしたbash
最初のシェル)では、連想配列がハッシュテーブルとして実装されているため、要素は特定の順序で格納されないため、上記のコードは要素を繰り返しランダムな順序で表示されます。 。