動的に作成された名前で参照される配列内の要素の数を見つける

動的に作成された名前で参照される配列内の要素の数を見つける

同様の質問を見つけましたここですが、同一ではないようで、どの回答も私が望む出力を提供していません。 配列があり、動的に生成された名前を使用してアクセスすることで、その配列に含まれる要素の数を見つけたいと考えています。

declare -a array0=(2 4 2 5)  # contains 4 values
indx=0
Name="array$indx"            # create a name reference => array0

# I know how to obtain an indexed value by INDIRECT reference:
val0=${!Name[0]}
# I also know how to get array length using DIRECT name
len=${#array0[@]}

必要なのは、配列0変数を使用して参照することで名前

len=${#!Name[@]}             # the syntax is incorrect

実装に関する提案はありますか?

編集:
これを使用して配列エントリにアクセスできるというのは間違いでした:

val0=${!Name[0]}

これは indx=0 の場合にのみ機能するため、配列から他のエントリを取得したい場合は、単に空の文字列を返します。

val4=${!Name[4]}          #does not work

または

i=4
val4=${!Name[$i]}         # does not work

答え1

またはそれ以上の場合bash-4.3、nameref を使用できます。

a0=(a b c)
i=0
typeset -n Name="a$i"
echo "${#Name[@]}"

またはいつでも使用evalいずれにせよ、bashnamerefsを使うことはより安全よりも優れていますeval。 の場合と同様にeval、 の内容が$Name有効なシェル変数名であることを確認する必要があります。 のような値は、または を展開するときにx[`evil-command>&2`0]依然として実行されます。 にも同じことが当てはまります。evil-command$Name${#Name}${!var}

ではksh93、代わりに多次元配列を使用できます。

a[0]=(a b c)
i=0
echo "${#a[i][@]}"

zsh展開演算子を組み合わせるより一貫した方法があります。

a0=(a b c)
i=0
name=a$i
echo ${(P)#name}

P間接パラメータ展開用)。

答え2

明示的に使用することもできますevalが、過度に使用しないでください。

eval "len=\${#$Name[@]}"

関連情報