2012-04-02 13 views
5

¿Cómo puedo poblar una matriz en bucle? Me gustaría hacer algo así:bash poblar una matriz en el bucle

declare -A results 

results["a"]=1 
results["b"]=2 

while read data; do 
results[$data]=1 
done 

for i in "${!results[@]}" 
do 
    echo "key : $i" 
    echo "value: ${results[$i]}" 
done 

pero parece que no puedo añadir nada a una matriz dentro de bucle. ¿Por qué?

+1

¿Qué versión de bash estás usando? – siride

Respuesta

13

Lo que debe funcionar, suponiendo que tiene una versión de Bash que admita matrices asociativas para empezar.

Si puedo tomar una conjetura salvaje. . . ¿está ejecutando algo como esto:

command_that_outputs_keys \ 
    | while read data; do 
     results[$data]=1 
    done 

? ¿Eso es — es su while parte del lazo de una tubería? Si es así, entonces que es el problema. Usted ve, cada comando en una tubería recibe una copia del entorno de ejecución del shell. Por lo tanto, el bucle while rellenaría una copia de la matriz results, y cuando se complete el bucle while, esa copia desaparecerá.

Editado para añadir: Si eso es el problema, entonces como glenn jackman puntos en un comentario, lo puede solucionar mediante el uso de process substitution lugar:

while read data; do 
    results[$data]=1 
done < <(command_that_outputs_keys) 

De esa manera, aunque command_that_outputs_keys recibirán solo una copia del entorno de ejecución del shell (como antes), el bucle while tendrá el entorno principal original, por lo que puede modificar el conjunto original.

+4

+1 la forma de evitar la subshell es usar la sustitución del proceso: 'while ... done <<(command here)' –

+0

@glennjackman: Brillante, gracias! Mi primer pensamiento fue "sustituir el proceso de uso", pero mi segundo pensamiento fue "ah, espera, eso sería reemplazado por un nombre de archivo, y' while' no sabría tomar el archivo como entrada ". '<<(...) 'tiene sentido ahora que lo sé, pero nunca hubiera adivinado que estaba permitido. He actualizado mi respuesta. ¡Gracias de nuevo! :-RE – ruakh

1

que parece estar funcionando bien:

$ cat mkt.sh 
declare -A results 

results["a"]=1 
results["b"]=2 

while read data; do 
    results[$data]=1 
done << EOF 
3 
4 
5 
EOF 

for i in "${!results[@]}" 
do 
    echo "key : $i" 
    echo "value: ${results[$i]}" 
done 

$ ./mkt.sh 
key : a 
value: 1 
key : b 
value: 2 
key : 3 
value: 1 
key : 4 
value: 1 
key : 5 
value: 1 
$ 

Ubuntu 11.10 aquí, bash: fiesta de GNU, versión 4.2.10 (1) -release (x86_64-pc-linux-gnu).