Você pode usar eval
explicitamente, mas não use em excesso:
eval "len=\${#$Name[@]}"
Encontrei uma pergunta semelhante aqui , mas não parece ser idêntico, e nenhuma das respostas fornece a saída que desejo. Eu tenho um array, para o qual eu quero encontrar quantos elementos ele contém, acessando-o usando o nome gerado dinamicamente.
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[@]}
O que eu preciso é encontrar o número de elementos do array0 referenciando-o usando a variável Nome
len=${#!Name[@]} # the syntax is incorrect
Alguma sugestão para implementação?
EDITAR:
Eu estava errado sobre ser capaz de acessar as entradas da matriz usando isso:
val0=${!Name[0]}
Ele só funciona para indx = 0, então, se eu quiser obter outras entradas da matriz, ele simplesmente retorna uma string vazia:
val4=${!Name[4]} #does not work
ou
i=4
val4=${!Name[$i]} # does not work
Com bash-4.3
ou acima, você pode usar namerefs:
a0=(a b c)
i=0
typeset -n Name="a$i"
echo "${#Name[@]}"
ou você sempre pode usar eval
. Em qualquer caso, não se engane pensando que usar bash
namerefs é mais seguro que eval
. Assim como para eval
, você ainda precisa garantir que o conteúdo de $Name
seja um nome de variável de shell válido. Valores como x['evil-command>&2'0]
ainda causariam a execução de evil-command
quando você expandir $Name
ou ${#Name}
. O mesmo se aplica a ${!var}
.
Com ksh93
, você pode usar matrizes multidimensionais:
a[0]=(a b c)
i=0
echo "${#a[i][@]}"
zsh
tem formas mais consistentes de combinar seus operadores de expansão:
a0=(a b c)
i=0
name=a$i
echo ${(P)#name}
( P
para expansão indireta de parâmetros).