Encuentre la cantidad de elementos en una matriz a la que hace referencia un nombre creado dinámicamente

Encuentre la cantidad de elementos en una matriz a la que hace referencia un nombre creado dinámicamente

encontré una pregunta similaraquí, pero no parece ser idéntico y ninguna de las respuestas proporciona el resultado que deseo. Tengo una matriz, para la cual quiero saber cuántos elementos contiene accediendo a ella usando un nombre generado dinámicamente.

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

Lo que necesito es encontrar el número de elementos delmatriz0haciendo referencia a él usando la variableNombre

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

¿Alguna sugerencia para la implementación?

EDITAR:
Me equivoqué al poder acceder a las entradas de la matriz usando esto:

val0=${!Name[0]}

Sólo funciona para indx=0, por lo que si quisiera obtener otras entradas de la matriz, simplemente devuelve una cadena vacía:

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

o

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

Respuesta1

Con bash-4.3o superior, puedes usar namerefs:

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

o siempre puedesusareval. En cualquier caso, no se deje engañar pensando que usar bashnamerefs esmás seguroque eval. Al igual que para eval, aún debe asegurarse de que el contenido de $Namesea un nombre de variable de shell válido. Valores como x[`evil-command>&2`0]aún harían que evil-commandse ejecute cuando expandas $Nameo ${#Name}. Lo mismo se aplica a ${!var}.

Con ksh93, podrías usar matrices multidimensionales en su lugar:

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

zshtiene formas más consistentes de combinar sus operadores de expansión:

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

( Ppara expansión de parámetros indirectos).

Respuesta2

Puedes usarlo evalexplícitamente, pero no lo abuses:

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

información relacionada