417 votes

Comment itérer sur des tableaux associatifs en Bash ?

Sur la base d'un tableau associatif dans un script de Bash, j'ai besoin d'itérer sur celui-ci pour obtenir la clé et la valeur.

#!/bin/bash

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

En fait, je ne comprends pas comment obtenir la clé en utilisant une boucle for-in.

17 votes

$ declare -A array=( [foo]=bar [bar]=foo ) # Initialise tout en une fois

3 votes

Pour une petite liste de valeurs clés, vous pouvez envisager ceci : for i in a,b c_s,d ; do KEY=${i%,*}; VAL=${i#*,}; echo $KEY" XX "$VAL; done

678voto

Dennis Williamson Points 105818

Les touches sont accessibles à l'aide d'un point d'exclamation : ${!array[@]} le valeurs sont accessibles en utilisant ${array[@]} .

Vous pouvez itérer sur les paires clé/valeur comme ceci :

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

Notez l'utilisation de guillemets autour de la variable dans le champ for (plus l'utilisation de @ au lieu de * ). Ceci est nécessaire au cas où certaines clés comporteraient des espaces.

La confusion dans l'autre réponse vient du fait que votre question inclut "foo" et "bar" pour les deux clés. et les valeurs.

4 votes

C'est maintenant si on assigne toutes les clés à un tableau : array=(${!hash[@]})

16 votes

@Michael-O : Vous devez citer l'expansion du paramètre pour protéger les clés qui peuvent avoir des espaces : array=("${!hash[@]}")

0 votes

@DennisWilliamson, merci beaucoup. Je n'avais pas ça à l'esprit.

56voto

tonio Points 5773

Vous pouvez accéder aux clés avec ${!array[@]} :

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

Ensuite, l'itération sur les paires clé/valeur est facile :

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

1 votes

J'avais le " !" - je n'ai même pas remarqué, il n'y en avait pas, désolé.. :)

0 votes

echo "${!array[@]}" n'a pas fonctionné sur ma machine. J'utilise un Mac.

12voto

Utilisez cette fonction d'ordre supérieur pour éviter que le pyramide de malheur

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

exemple :

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

1 votes

Je ne vois pas bien en quoi cela est applicable. La pyramide de la mort n'est-elle pas une question purement esthétique et n'est-elle vraiment applicable qu'aux langages orientés objet ?

1 votes

Pourriez-vous l'expliquer ? La fonction foreach est un peu délicate. Je ne comprends pas.

4voto

mOmOney Points 67

Bienvenue au tableau associatif d'entrée 2.0 !

    clear
    echo "Welcome to input associative array 2.0! (Spaces in keys and values now supported)"
    unset array
    declare -A array
    read -p 'Enter number for array size: ' num
    for (( i=0; i < num; i++ ))
        do
            echo -n "(pair $(( $i+1 )))"
            read -p ' Enter key: ' k
            read -p '         Enter value: ' v
            echo " "
            array[$k]=$v
        done
    echo " "
    echo "The keys are: " ${!array[@]}
    echo "The values are: " ${array[@]}
    echo " "
    echo "Key <-> Value"
    echo "-------------"
    for i in "${!array[@]}"; do echo $i "<->" ${array[$i]}; done
    echo " "
    echo "Thanks for using input associative array 2.0!"

Sortie :

Welcome to input associative array 2.0! (Spaces in keys and values now supported)
Enter number for array size: 4
(pair 1) Enter key: Key Number 1
         Enter value: Value#1

(pair 2) Enter key: Key Two
         Enter value: Value2

(pair 3) Enter key: Key3
         Enter value: Val3

(pair 4) Enter key: Key4
         Enter value: Value4

The keys are:  Key4 Key3 Key Number 1 Key Two
The values are:  Value4 Val3 Value#1 Value2

Key <-> Value
-------------
Key4 <-> Value4
Key3 <-> Val3
Key Number 1 <-> Value#1
Key Two <-> Value2

Thanks for using input associative array 2.0!

Tableau associatif d'entrée 1.0

(les clés et les valeurs qui contiennent des espaces ne sont pas prises en charge)

    clear
    echo "Welcome to input associative array! (written by mO extraordinaire!)"
    unset array
    declare -A array
    read -p 'Enter number for array size: ' num
    for (( i=0; i < num; i++ ))
        do
            read -p 'Enter key and value separated by a space: ' k v
            array[$k]=$v
        done
    echo " "
    echo "The keys are: " ${!array[@]}
    echo "The values are: " ${array[@]}
    echo " "
    echo "Key <-> Value"
    echo "-------------"
    for i in ${!array[@]}; do echo $i "<->" ${array[$i]}; done
    echo " "
    echo "Thanks for using input associative array!"

Sortie :

Welcome to input associative array! (written by mO extraordinaire!)
Enter number for array size: 10
Enter key and value separated by a space: a1 10
Enter key and value separated by a space: b2 20
Enter key and value separated by a space: c3 30
Enter key and value separated by a space: d4 40
Enter key and value separated by a space: e5 50
Enter key and value separated by a space: f6 60
Enter key and value separated by a space: g7 70
Enter key and value separated by a space: h8 80
Enter key and value separated by a space: i9 90
Enter key and value separated by a space: j10 100

The keys are:  h8 a1 j10 g7 f6 e5 d4 c3 i9 b2
The values are:  80 10 100 70 60 50 40 30 90 20

Key <-> Value
-------------
h8 <-> 80
a1 <-> 10
j10 <-> 100
g7 <-> 70
f6 <-> 60
e5 <-> 50
d4 <-> 40
c3 <-> 30
i9 <-> 90
b2 <-> 20

Thanks for using input associative array!

-2voto

EJISRHA Points 9
declare -a arr
echo "-------------------------------------"
echo "Here another example with arr numeric"
echo "-------------------------------------"
arr=( 10 200 3000 40000 500000 60 700 8000 90000 100000 )

echo -e "\n Elements in arr are:\n ${arr[0]} \n ${arr[1]} \n ${arr[2]} \n ${arr[3]} \n ${arr[4]} \n ${arr[5]} \n ${arr[6]} \n ${arr[7]} \n ${arr[8]} \n ${arr[9]}"

echo -e " \n Total elements in arr are : ${arr[*]} \n"

echo -e " \n Total lenght of arr is : ${#arr[@]} \n"

for (( i=0; i<10; i++ ))
do      echo "The value in position $i for arr is [ ${arr[i]} ]"
done

for (( j=0; j<10; j++ ))
do      echo "The length in element $j is ${#arr[j]}"
done

for z in "${!arr[@]}"
do      echo "The key ID is $z"
done
~

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X