Usando um loop for para fazer o loop sobre vários arrays no bash

5

O Bash não suporta nativamente arrays bidimensionais , mas eu gostaria de simular um. Como um exemplo de trabalho mínimo, suponha que eu tenha duas matrizes, a0 e a1 :

a0=(1 2 3 4)
a1=(5 6 7 8)

Eu quero escrever um loop for que imprimirá o terceiro elemento de a0 e a1 . Claro, eu poderia fazer isso manualmente com duas chamadas explícitas para echo :

echo ${a0[2]}
echo ${a1[2]}

Mas, quero generalizar isso com um loop for . Como posso fazer isso?

Eu tentei o seguinte:

for i in ${a0[@]} ${a1[@]}
do
echo {$i}[2]
echo ${i[2]}
echo ${i}[2]
echo ${$i[2]}
echo ${${i}[2]}
done

Mas nenhuma dessas tentativas é bem sucedida; Eu recebo esta saída:

{1}[2]

1[2]
chgreen.sh: line 30: ${$i[2]}: bad substitution

Você tem alguma ideia?

    
por Andrew 05.11.2014 / 21:09

3 respostas

3

Como você já deve ter aprendido da sua pesquisa, o bash não suporta matrizes multidimensionais per se , mas suporta matrizes "associativas". Estes são basicamente indexados por uma string, ao invés de um número, então você pode ter, por exemplo,

grade[John]=100
grade[Paul]=100
grade[George]=90
grade[Ringo]=80

Como demonstrado (mas não explicado muito bem) na resposta aceita da questão que você vinculou, os índices de matrizes associativas podem conter vírgulas, e assim um truque comum é concatenar seus índices individuais (0-1 × 0-3) em uma string, separados por vírgulas. Embora isso seja mais complicado do que os arrays comuns, pode ser eficaz:

$ declare -A a              <-- Create the associative array.
$ a[0,0]=1
$ a[0,1]=2
$ a[0,2]=3
$ a[0,3]=4
$ a[1,0]=5
$ a[1,1]=6
$ a[1,2]=7
$ a[1,3]=8
$ for i in 0 1
> do
>     echo ${a[$i,2]}
> done
3                           <-- And here’s your output.
7
    
por 06.11.2014 / 02:22
3

Você está interagindo com a coisa errada. Seu for salva cada elemento da matriz como $i , não os índices da matriz. O que você quer é algo como

#!/usr/bin/env bash
a0=(1 2 3 4)
a1=(5 6 7 8)

for ((i=0;i<${#a0[@]};i++))
do
    echo ${a0[$i]} ${a1[$i]};
done
    
por 05.11.2014 / 21:17
0

Esta é uma maneira estranha de fazer isso, mas pode ser útil em alguns casos. O problema é que o loop for resolverá seus arrays em seus elementos e tratará cada elemento separadamente.

Portanto, desconstrua seus arrays e faça-os novamente.

a0=(1 2 3 4)
a1=(5 6 7 8)
a0=${a0[@]}  # deconstruction
a1=${a1[@]}
for arr in "$a0" "$a1"; do a=( $arr ); echo ${a[2]}; done

Saída

3

7

    
por 24.08.2018 / 02:26