web-dev-qa-db-fra.com

Itérer sur deux tableaux simultanément dans bash

J'ai deux tableaux.

array=(
  Vietnam
  Germany
  Argentina
)
array2=(
  Asia
  Europe
  America
)

Je souhaite effectuer une boucle simultanée sur ces deux tableaux, c’est-à-dire appeler une commande sur les premiers éléments des deux tableaux, puis invoquer la même commande sur les deuxièmes éléments, et ainsi de suite. Pseudocode:

for c in $(array[*]}
do
  echo -e " $c is in ......"
done

Comment puis-je faire ceci?

67
user2354862

À partir de la réponse d’Anishsane et des commentaires qu’elle contient, nous savons maintenant ce que vous voulez. Voici la même chose dans un style bashier , en utilisant une boucle for. Voir la section Constructions en boucle dans le manuel de référence . J'utilise aussi printf au lieu de echo.

#!/bin/bash

array=( "Vietnam" "Germany" "Argentina" )
array2=( "Asia" "Europe" "America" )

for ((i=0;i<${#array[@]};++i)); do
    printf "%s is in %s\n" "${array[i]}" "${array2[i]}"
done

Une autre possibilité serait d'utiliser un tableau associatif:

#!/bin/bash

declare -A continent

continent[Vietnam]=Asia
continent[Germany]=Europe
continent[Argentina]=America

for c in "${!continent[@]}"; do
    printf "%s is in %s\n" "$c" "${continent[$c]}"
done

Selon ce que vous voulez faire, vous pouvez aussi envisager cette deuxième possibilité. Mais notez que vous ne contrôlerez pas facilement l'ordre d'affichage des champs dans la deuxième possibilité (enfin, c'est un tableau associatif, donc ce n'est pas vraiment une surprise).

83
gniourf_gniourf

Si tous les tableaux sont correctement ordonnés, il suffit de faire passer l'index.

array=(
  Vietnam
  Germany
  Argentina
)
array2=(
  Asia
  Europe
  America
)

for index in ${!array[*]}; do 
  echo "${array[$index]} is in ${array2[$index]}"
done

Vietnam is in Asia
Germany is in Europe
Argentina is in America
31
cthomaspdx

Vous avez besoin d'une boucle sur array & array2

i=0
while [ $i -lt ${#array[*]} ]; do
    echo ${array[$i]} is in ${array2[$i]}
    i=$(( $i + 1));
done

Vietnam is in Asia
Germany is in Europe
Argentina is in America

Alternativement, vous pouvez utiliser cette option (sans boucle):

paste <(tr ' ' '\n' <<< ${array[*]}) <(tr ' ' '\n' <<< ${array2[*]}) | sed 's/\t/ is in /'
12
anishsane

Spécifiquement pour la question posée (tableaux avec 3 éléments):

for i in $(seq 0 2) ; do echo "${array1[$i]} is in ${array2[$i]}" ; done

0
runlevel0

Si les deux vars étaient deux chaînes avec plusieurs lignes, comme ceci:

listA=$(echo -e "Vietnam\nGermany\nArgentina")
listB=$(echo -e "Asia\nEurope\nAmerica")

Ensuite, la solution pour ce cas est la suivante:

while read strA <&3 && read strB <&4; do
   echo "$strA is in $strB"
done 3<<<"$listA" 4<<<"$listB"
0