A página do manual Bash descreve o uso de ${!a}
para retornar o conteúdo da variável cujo nome é o conteúdo de a
(um nível de indireção).
Eu gostaria de saber como retornar todos os elementos em uma matriz usando isso, ou seja,
a=(one two three)
echo ${a[*]}
retorna
one two three
Eu gostaria de:
b=a
echo ${!b[*]}
para retornar o mesmo. Infelizmente, não, mas retorna 0
.
Atualizar
Dadas as respostas, agora percebo que meu exemplo era muito simples, pois é claro, algo como:
b=("${a[@]}")
Alcançará exatamente o que eu disse que precisava.
Então, aqui está o que eu estava tentando fazer:
LIST_lys=(lys1 lys2)
LIST_diaspar=(diaspar1 diaspar2)
whichone=$1 # 'lys' or 'diaspar'
_LIST=LIST_$whichone
LIST=${!_LIST[*]}
Obviamente, a leitura cuidadosa da página de manual do Bash mostra que isso não funcionará conforme o esperado, porque a última linha simplesmente retorna os índices da "matriz" $_LIST
(não uma matriz).
Em qualquer caso, o seguinte deve fazer o trabalho (conforme indicado):
LIST=($(eval echo \${$_LIST[*]}))
ou ... (a rota que segui, eventualmente):
LIST_lys="lys1 lys2"
...
LIST=(${!_LIST})
Supondo, é claro, que os elementos não contenham espaços em branco.
[@]
ao ponteiro_LIST="LIST_${whichone}[@]"
e, em seguida, useLIST=("${!_LIST}")
para copiar a matriz. É uma boa idéia usar nomes de variáveis em minúsculas para evitar conflitos com variáveis de ambiente (Todas as maiúsculas).Respostas:
Eu acho que o uso de referência indireta da variável bash deve ser tratado literalmente.
Por exemplo. Para o seu exemplo original:
Para o último cenário real, acredito que o código abaixo faria o trabalho.
É melhor usar a notação
"${var[@]}"
que evita bagunçar a$IFS
expansão dos parâmetros e. Aqui está o código final.fonte
Você precisa copiar os elementos explicitamente. Para uma matriz indexada:
Para uma matriz associativa (observe que
a
é o nome da variável da matriz, não uma variável cujo valor seja o nome de uma variável da matriz):Se você tiver o nome da variável em uma matriz, poderá usar o método elemento a elemento com uma etapa extra para recuperar as chaves.
(Aviso, o código nesta postagem foi digitado diretamente em um navegador e não foi testado.)
fonte
\${!$name[@]}
na primeira linha, para que a primeira expansão seja apenas '$ name' e${!a[@]}
seja salva para o eval, e a mesma coisa no loop for, com\${$name}
. As outras duas barras invertidas antes de '$ k' também não são estritamente necessárias.${!b[*]}
expande para os índices usados na matrizb
.O que você gostaria que tem de ser feito em duas etapas, por isso
eval
vai ajudar:eval echo \${$b[*]}
. (Observe o\
que garante que a primeira$
passará na primeira etapa, a expansão variável e será expandida apenas na segunda etapaeval
).De acordo com o Parâmetro, a expansão
!
é usada para expansão indireta ({!a}
), nomes correspondentes ao prefixo (${!a*}
) e lista de chaves de matriz (${!a[*]}
). Como a Lista de chaves da matriz possui a mesma sintaxe que a expansão indireta pretendida + a expansão do elemento da matriz, a versão mais recente não é suportada.fonte
${!a}
se expande para o valor da variável cujo nome é$a
. Isso é descrito de maneira bastante detalhada no manual, no parágrafo que começa com "Se o primeiro caractere do parâmetro for um ponto de exclamação (!
), é introduzido um nível de indireção variável".${!
é meio ambíguo, já que se você está lidando com uma matriz, o comportamento é diferente.Para acessar matrizes indiretamente, basta adicionar
[@]
à variável indiretab=a[@]
.Se essas variáveis estiverem definidas:
Então, isso funcionará:
Ou simplesmente:
Essa matriz pode ser copiada como esta:
E depois impresso com:
Em um script:
Obviamente, todas as opções acima copiarão uma matriz não esparsa. Um em que todos os índices têm um valor.
matrizes esparsas
Uma matriz esparsa é aquela que pode ter elementos não definidos.
Por exemplo,
a[8]=1234
define um elemento e, no bash, de 0 a 7 não existe.Para copiar essa matriz esparsa, use este método
Imprima a matriz antiga:
Substitua o nome da matriz e capture a sequência:
Para avaliar a string criada, a nova matriz foi definida:
fonte