Найти количество элементов в массиве, на который ссылается динамически созданное имя.

Найти количество элементов в массиве, на который ссылается динамически созданное имя.

Я нашел похожий вопросздесь, но он, похоже, не идентичен, и ни один из ответов не дает нужного мне результата. У меня есть массив, для которого я хочу узнать, сколько элементов он содержит, обращаясь к нему с помощью динамически сгенерированного имени.

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или выше вы можете использовать namerefs:

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[@]}"

Связанный контент