Bash配列の間接参照

Bash配列の間接参照

ループなしで次のスクリプトを書くことはできますか?

IPv4_first=1.1.1.1
IPv4_second=2.2.2.2
IPv4_third=3.3.3.3

IPv4_all=() 

for var in ${!IPv4_@}
do
   IPv4_all+=(${!var})
done

printf "'%s'\n" "${IPv4_all[@]}"

それは次のとおりです。

IPv4_all=${!${!IPv4_@}}

ベストアンサー1

これはおそらく私が書いたものの中で最も醜いBashコードです。しかし...

IPv4_first=1.1.1.1
IPv4_second=2.2.2.2
IPv4_third=3.3.3.3

names=(${!IPv4_@})
eval "IPv4_all=(${names[@]/#/$})"
printf "'%s'\n" "${IPv4_all[@]}"

見て、お母さん、ループがありません!

${names[@]/#/$}プレフィックス $各要素の先頭に固定された空の文字列を一致させ、配列の各要素の先頭に連結します。これはeval、配列イニシャライザ内で変数参照を取得するために拡張できる変数逆参照配列を提供します。複数のパラメータ拡張を同時に適用できないため、2つの別々の行が必要です。

出力は次のとおりです

'1.1.1.1'
'2.2.2.2'
'3.3.3.3'

予想通り。

この行は次のように置き換えることができます。

IPv4_all=($(eval "echo ${names[@]/#/$}"))

evalリング配列割り当ての代わりに。これが良いかどうかはわかりません。

変数の値にスペースやその他のIFS文字を含めることができる場合は、evalを変更できます。

eval "IPv4_all=($(printf '"$%s" ' "${names[@]}"))"

これはすべての変数を二重引用符で正しく引用します。

おすすめ記事