名前を変数として参照して bash 配列を検索します。

名前を変数として参照して bash 配列を検索します。

Bash 拡張の助けが必要です。
配列値GNU bash 5.1.0を検索したいです。配列名は変数でなければなりません。 bashで変数を参照する「ただ」です。

$gral変数には名前を持つ「armin」という配列があります(うまくいきます)。

gral="armin"

課題:

declare -a ${gral}[1]="milk"
declare -a ${gral}[2]="cow"
declare  ${gral}[7]="budgie"
declare  ${gral}[9]="pla9ne"

美しい。

配列が存在します。

$ echo ${armin[@]}
milk cow budgie pla9ne

配列インデックスが存在します。

$echo ${!armin[@]}
1 2 7 9

配列とインデックスは大丈夫です。

配列を参照して配列を検索したいと思います。変数に名前を付ける、手動ではありません。
以前に設定され使用されていた多くの変数があります。

$ echo $gral
armin  ## name of our bash array

とても良い - 今までは。

変数を使用せずに違いを表示するには:

echo ${armin[@]}
milk cow budgie pla9ne

次に、変数(gral)を参照して名前(armin)を呼び出してみてください。

$ echo ${$gral[@]}
-bash: ${$gral[@]}: wrong substitution.

$echo ${"$gral"[@]}
-bash: ${"$gral"[@]}: wrong substitution.
echo ${"gral"[@]}
-bash: ${"gral"[@]}: wrong substitution.
echo ${${gral}[@]}
-bash: ${${gral}[@]}: wrong substitution.

すべて失敗しました。 「eval」も試しました。関連(statement-A)を使用しても違いはありません。

注:索引付けはこの方法で問題なくうまく機能します。名前が問題ですね。

何か抜けていると思います。おそらく答えは以前に説明されたでしょう。私は配列の変数に関する興味深い内容をたくさん見つけましたが、私の課題に対する答えを特定できませんでした。

できますか?配列名を変数として参照して、配列を検索する用語を見つけるのに役立ちます。

答え1

namerefを使用する(Bash> = 4.3):

$ armin=(foo bar doo)
$ declare -n gral=armin      # 'gral' references array 'armin'  
$ gral[123]=quux             # same as 'armin[123]=quux'
$ echo "${gral[@]}"
foo bar doo quux
$ echo "${gral[1]}"
bar
$ echo "${!gral[@]}"         # listing the indexes works too
0 1 2 123

また見なさい:Bashはポインタの使用をサポートしていますか?

答え2

@ilkkachuが答えたように、namerefsはここで使用されるツールです。これにより、配列を関数に渡すのは非常に簡単です。たとえば、

dumpArray() {
  local -n ary=$1
  for i in "${!ary[@]}"; do
    printf "%s\t%s\n" "$i" "${ary[$i]}"
  done
}

この関数は配列と関連配列を処理できます。

$ declare -a armin=([1]=milk [2]=cow [7]=bugle [9]=pla9ne)

$ dumpArray armin
1   milk
2   cow
7   bugle
9   pla9ne

$ declare -A map=([foo]=bar [baz]=qux)

$ dumpArray map
foo bar
baz qux

唯一の実際の問題は、namerefに同じ名前の配列を参照させることが混乱していることです。

$ ary=(a b c)

$ dumpArray ary
bash: local: warning: ary: circular name reference
bash: warning: ary: circular name reference
bash: warning: ary: circular name reference
bash: warning: ary: circular name reference
bash: warning: ary: circular name reference
0   a
bash: warning: ary: circular name reference
bash: warning: ary: circular name reference
1   b
bash: warning: ary: circular name reference
bash: warning: ary: circular name reference
2   c

そのため、関数の配列に次のような奇妙な名前を付けます。

dumpArray() {
  local -n __dumpArray_ary=$1
  do_stuff_with "${__dumpArray_ary[@]}"
}

答え3

[@]名前を含む変数に「インデックス」を含めます。例:

ref=$gral'[@]'
printf '%s\n' "${!ref}"

出力:

milk
cow
budgie
pla9ne

スペースを含む値にも機能します。

答え4

まあ、
答えは変数として渡された名前で配列を逆参照する(部分的にポインタに似ています)
は(上記の例を再利用):

eval echo "\$$(eval echo "{$gral[@]}")"
$gralは配列名を格納します。

結果:

牛愛オウムpla9ne

このソリューションを拡張して、インデックスエントリを使用してbash配列(インデックス付きおよび関連付け)コンテンツを繰り返すことができます。

答えを見つけてとても嬉しいです。みんなの助けをありがとう!

変数の内容にアクセスします。

ABSガイドには結果につながるヒントがあります。
https://tldp.org/LDP/abs/html/abs-guide.html#IVR

メンデルクーパーの貢献ありがとうございます。高度なバッシュスクリプトガイド

まあ、
安全上の理由から評価が醜いです。
より良いものを見つける...

関連情報