文字列値に基づいて配列を呼び出す

文字列値に基づいて配列を呼び出す

次のように、文字列変数で名前が定義されているbashスクリプトから配列を呼び出す必要があります。

var="array"
array=( 
1
2
3
)

$ varは常に配列名と同じです。

#failed attempts at echoing ${array[@]}
echo "${!var}          # returns only the first value of the array

echo "${!var[@]}"      # returns 0

tempvar='${'$var'[@]}' # makes a new variable with value of "${array[@]}"
echo "${!tempvar}"     #returns 'invalid variable name'

私はこの問題に初めて触れ、この問題に対する解決策を見つけることができませんでした。よろしくお願いします。

答え1

バッシュ固有

配列を参照するには、「nameref」を使用してください。declare -n

array=(1 2 3)
var=array

declare -n a=$var

for idx in "${!a[@]}"; do echo "$idx -> ${a[idx]}"; done
a[4]="hello"
declare -p a array     # original altered by above assignment

出力

0 -> 1
1 -> 2
2 -> 3
declare -n a="array"
declare -a array=([0]="1" [1]="2" [2]="3" [4]="hello")

何かを作るコピー配列では間接変数を使用してください。見苦しいです。

tmp=${var}[@]          # constructing a string
b=( "${!tmp}" )        # indirect variable expansion
b[4]="goodbye"

declare -p tmp b array     # original not changed

出力

declare -- tmp="array[@]"
declare -a b=([0]="1" [1]="2" [2]="3" [3]="hello" [4]="goodbye")
declare -a array=([0]="1" [1]="2" [2]="3" [4]="hello")

「hello」要素のインデックスがどのように変更されるかを確認してくださいb。これはb=("${!tmp}")、配列の一意のコピーが作成されるためです。要素、いいえ索引

答え2

bashでは(kshと同じようにbashは配列デザインをコピーしました)配列は通常の配列と同じではありませんが、まれな配列したがって、キーは正の整数に制限された連想配列に似ています。

ここでは、次のことができます。

$ array=( [12]=a [23]=b [34]=c )
$ var=array
$ tempvar_for_separated_out_keys='!'$var[@]
$ tempvar_for_separated_out_values=$var[@]
$ printf -- '- <%s>\n' "${!tempvar_for_separated_out_keys}"
bash: !array[@]: invalid variable name
$ printf -- '- <%s>\n' "${!tempvar_for_separated_out_values}"
- <a>
- <b>
- <c>

(はい、コアはまだ機能していません)。

代わりに、namerefを使用することもできます(kshでも利用可能ですが、いくつかの違いがあります)。

$ typeset -n var=array
$ printf -- '- <%s>\n' "${!var[@]}"
- <12>
- <23>
- <34>
$ printf -- '- <%s>\n' "${var[@]}"
- <a>
- <b>
- <c>

zshまたは、パラメータ拡張フラグを使用して、逆参照が実行される場所に切り替えることもできますPzsh配列は配列ですが、キーが任意の文字列(バイトまたは文字)である適切な連想配列もあります。

$ array=( a b c '' ) var=array
$ printf -- '- <%s>\n' ${(P)var}
- <a>
- <b>
- <c>
$ printf -- '- <%s>\n' "${(P@)var}"
- <a>
- <b>
- <c>
- <>
$ typeset -A hash=( 12 a 23 b 34 c '' empty )
$ var=hash
$ printf -- '- <%s>\n' "${(Pk@)var}"
- <>
- <34>
- <23>
- <12>
$ printf -- '- <%s>\n' "${(Pv@)var}"
- <empty>
- <c>
- <b>
- <a>
$ printf -- '- <%s> -> <%s>\n' "${(Pkv@)var}"
- <> -> <empty>
- <34> -> <c>
- <23> -> <b>
- <12> -> <a>

kでマークvでマーク価値(デフォルト)、@Bourneシェルのように空の要素を保存するために引用符で囲まれています"$@"

関連情報