2010-06-24 17 views
224

Sobre la base de una matriz asociativa en un script Bash, necesito iterar sobre ella para obtener la clave y valor.Cómo iterar sobre matrices asociativas en Bash

#!/bin/bash 

declare -A array 
array[foo]=bar 
array[bar]=foo 

En realidad no entiendo cómo conseguir la llave mientras se utiliza un bucle for-in.

+6

$ declaran -A matriz = ([foo] = bar [bar] = foo) # inicializar todos en una vez – anisbet

+2

Para obtener una lista pequeña de valores clave, puede considerar esto: 'para i en a, b c_s, d; do KEY = $ {i%, *}; VAL = $ {i # *,}; echo $ KEY "XX" $ VAL; hecho' – math

Respuesta

400

Las teclas se accede mediante un signo de exclamación: ${!array[@]}, la valores se accede utilizando ${array[@]}.

Puede iterar sobre los pares clave/valor como este:

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

Nota el uso de comillas alrededor de la variable en la instrucción for (más el uso de @ en lugar de *). Esto es necesario en caso de que cualquier tecla incluya espacios.

La confusión en la otra respuesta proviene del hecho de que su pregunta incluye "foo" y "bar" para las claves y los valores.

+2

Esto es ahora si asigna todas las claves a una matriz: 'array = ($ {! hash [@]})' –

+7

@ Michael-O: Necesita para citar la expansión de parámetros para proteger las claves que pueden tener espacios en blanco: 'array = (" $ {! hash [@]} ")' –

+0

@DennisWilliamson, muchas gracias. No tenía esto en mente. –

35

Puede acceder a las llaves con ${!array[@]}:

bash-4.0$ echo "${!array[@]}" 
foo bar 

A continuación, iterar sobre los pares clave/valor es fácil:

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

perfecto - gracias! – pex

+1

Tuve el "!" - Ni siquiera se dio cuenta, no había ninguno, lo siento ... :) – pex

4

Utilice esta función de orden superior para evitar que el ejemplo pyramid of doom

foreach(){ 
    arr="$(declare -p $1)" ; eval "declare -A f="${arr#*=}; 
    for i in ${!f[@]}; do $2 "$i" "${f[$i]}"; done 
} 

:

$ bar(){ echo "$1 -> $2"; } 
$ declare -A foo["flap"]="three four" foo["flop"]="one two" 
$ foreach foo bar 
flap -> three four 
flop -> one two 
+1

No estoy seguro de cómo esto es aplicable? ¿No es la pirámide de la perdición un problema puramente estético y realmente solo aplicable en los lenguajes orientados a objetos? –

+1

¿podría explicarlo? La función foreach es un poco complicada. No lo entiendo –

Cuestiones relacionadas