Valores de matriz bash como variáveis dentro do loop

0

Eu estou tentando loop duplo usando valores de matriz como nomes de matriz para loop

array1="name1 name2"
name1="one two"
name2="red blue"

for name in $array1
do 
  for value in $name
  do
    echo "$name - $value"
  done
done

Eu preciso usar 'name' para '$ name' para usar no segundo loop, mas isso não funciona para mim.
Como eu poderia usar o valor de array1 como o nome do array dentro do segundo loop?

    
por Eloy Sanchez 10.06.2016 / 08:25

3 respostas

5

Não é assim que você define matrizes em bash .

a="foo bar"

define uma variável string / escalar. E usá-lo como $a (sem aspas) executa o operador split + glob que só faz sentido para strings representando uma lista de padrões de arquivo separados por $IFS .

Em bash , as matrizes são definidas como:

a=(foo bar)

Então, aqui, você quer:

array1=(name1 name2)
name1=(one two)
name2=(red blue)


for name in "${array1[@]}"
do
  typeset -n nameref="$name"
  for value in "${nameref[@]}"
  do
    printf '%s\n' "$name - $value"
  done
done

typeset -n é uma adição relativamente recente a bash e declara um nameref , que é uma variável que contém o nome de outra variável e quando expandida na verdade se refere à variável nomeada.

    
por 10.06.2016 / 09:32
2

Uma simples alteração de for value in $name para for value in ${!name} fará seu script funcionar corretamente:

array1="name1 name2"; name1="one two"; name2="red blue"

for       name  in $array1     ; do 
    for   value in ${!name}    ; do
          printf '%s - %s\n' "$name" "$value"
    done
done

No entanto, deve ser apontado que a variável chamada array1 é uma string, não uma matriz, não em todos.
Se você deseja trabalhar com matrizes:

#!/bin/bash

array1=(name1 name2)
name1=(one two)
name2=(red blue)

for       name  in "${array1[@]}"     ; do
          ref="${name}[@]"
    for   value in "${!ref}"          ; do
          printf '%s - %s\n' "$name" "$value"
    done
done

Indirection funciona do bash 2.0 (1997) e acima. Em vez de nameref, que é uma adição recente 4.3.

    
por 10.06.2016 / 23:54
1

Como Stéphane Chazelas aponta, uma lista de palavras não é a mesma. No entanto, você pode usar expansão indireta como esta:

array1="name1 name2"
name1="one two"
name2="red blue"

for name in ${array1}
do
    for value in ${!name}
    do
        echo "$name - $value"
    done
done

Nesse caso, ${!name} introduz um nível de indireção.

    
por 10.06.2016 / 10:51