
Encontrei uma pergunta semelhanteaqui, mas não parece ser idêntico e nenhuma das respostas fornece a saída que desejo. Eu tenho uma matriz para a qual desejo descobrir quantos elementos ela contém, acessando-a usando um 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 domatriz0referenciando-o usando a variávelNome
len=${#!Name[@]} # the syntax is incorrect
Alguma sugestão para implementação?
EDITAR:
Eu estava errado sobre poder acessar as entradas da matriz usando isto:
val0=${!Name[0]}
Funciona apenas para indx=0, então se eu quiser obter outras entradas do array, ele simplesmente retornará uma string vazia:
val4=${!Name[4]} #does not work
ou
i=4
val4=${!Name[$i]} # does not work
Responder1
Com bash-4.3
ou superior, você pode usar namerefs:
a0=(a b c)
i=0
typeset -n Name="a$i"
echo "${#Name[@]}"
ou você sempre podeusareval
. De qualquer forma, não se engane pensando que usar bash
namerefs émais seguraque eval
. Assim como for eval
, você ainda precisa ter certeza de que o conteúdo de $Name
é um nome de variável de shell válido. Valores como x[`evil-command>&2`0]
ainda fariam com que isso evil-command
fosse executado quando você expandisse $Name
ou ${#Name}
. O mesmo se aplica a ${!var}
.
Com ksh93
, você poderia 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).
Responder2
Você pode usar eval
explicitamente, mas não abuse:
eval "len=\${#$Name[@]}"