その配列の変数名を保持する別の配列内の複数の配列を参照するスクリプトを作成したいと思います。
これは私のコードです。
#!/bin/bash
array1=('array1string1' 'array1string2')
array2=('array2string1' 'array2string2')
array_names=('array1' 'array2')
for a in ${array_names[@]}
do
for b in ${a[@]}
do
echo $b
done
done
出力で両方の配列(外部forループで)をスキャンし、echoを呼び出す内部forループからその文字列を印刷したいと思います。私の現在の出力には以下が表示されます。
array1
array2
この問題に関するアドバイスをいただきありがとうございます。ありがとうございます!
答え1
バッシュ4.3以上「名前参照」またはnamerefをサポートします(同様のksh93
概念範囲の違いが迷惑です。):
#!/bin/bash
array1=('array1string1' 'array1string2')
array2=('array2string1' 'array2string2')
array_names=('array1' 'array2')
for a in "${array_names[@]}"; do
declare -n arr="$a"
for b in "${arr[@]}"; do
echo "$b"
done
done
変数は、arr
名前付き変数(この場合は名前を持つ変数)のエイリアスのように機能するnamerefです。$a
namerefがなければ、以前のバージョンのBashの1つの解決策は、他の配列のすべての要素を含む新しい配列を作成することでした。
all=( "${array1[@]}" "${array2[@]}" )
array_names
...質問の配列に似ていますが、すべての配列の内容を含めて繰り返します"${all[@]}"
。
また動作しますeval
が、生成されたコードは本当に悪いようです。
バラよりグレンジャックマンの答え可変間接参照を持つバリアント(Bashバージョン2で現在の形式で導入されています)
答え2
@Kusalanandaは最新バージョンのbashに最高の答えを提供します。以前のバージョンでは、間接変数を使用できます。
for a in ${array_names[@]}; do
tmp="${a}[@]"
for b in "${!tmp}"; do echo "$b"; done # or: printf "%s\n" "${!tmp}"
done
セクション4を参照https://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion
答え3
上記の変形で:
#!/bin/bash
array1=('array1 string1' 'array1 string2')
array2=('array2 string1' 'array2 string2')
array_names=('array1' 'array2')
for (( i=0; i<${#array_names[@]}; i++ )); do
declare -n arr="${array_names[i]}"
for (( j=0; j<${#arr[@]}; j++ )); do
echo "${arr[j]}"
done
done
インデックスで要素にアクセスする