Iterate over two arrays simultaneously in bash

ArraysBashLoops

Arrays Problem Overview


I have two arrays.

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

I want to loop over these two arrays simulataneously, i.e. invoke a command on the first elements of the two arrays, then invoke the same command on the second elements, and so on. Pseudocode:

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

How can I do this?

Arrays Solutions


Solution 1 - Arrays

From anishsane's answer and the comments therein we now know what you want. Here's the same thing in a bashier style, using a for loop. See the Looping Constructs section in the reference manual. I'm also using printf instead of echo.

#!/bin/bash

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

for i in "${!array[@]}"; do
    printf "%s is in %s\n" "${array[i]}" "${array2[i]}"
done

Another possibility would be to use an associative array:

#!/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

Depending on what you want to do, you might as well consider this second possibility. But note that you won't easily have control on the order the fields are shown in the second possibility (well, it's an associative array, so it's not really a surprise).

Solution 2 - Arrays

If all of the arrays are ordered correctly just pass around the 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

Solution 3 - Arrays

You need a loop over 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

EDIT: Do not use the below tr based implementation. It will not work for array elements containing spaces. Not removing it so as to keep the comments relevant. See glenn jackman's comment instead of below answer.

/EDIT

Alternately, you can use this option (without loop):

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

Solution 4 - Arrays

Specifically for the question asked (arrays with 3 items):

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

Solution 5 - Arrays

If the two vars were two string with multiple lines, like this:

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

Then, the solution for this case is:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2354862View Question on Stackoverflow
Solution 1 - Arraysgniourf_gniourfView Answer on Stackoverflow
Solution 2 - ArrayscthomaspdxView Answer on Stackoverflow
Solution 3 - ArraysanishsaneView Answer on Stackoverflow
Solution 4 - Arraysrunlevel0View Answer on Stackoverflow
Solution 5 - ArraysFabrício PereiraView Answer on Stackoverflow