Итерации по двум массивам одновременно в bash
У меня есть два массива.
array=(
Vietnam
Germany
Argentina
)
array2=(
Asia
Europe
America
)
Я хочу циклически перебирать эти два массива одновременно, т.е. вызывать команду для первых элементов двух массивов, затем вызывать одну и ту же команду для вторых элементов и т.д. Псевдокод:
for c in $(array[*]}
do
echo -e " $c is in ......"
done
Как я могу это сделать?
Ответы
Ответ 1
Из ответа anishsane и комментариев в нем мы теперь знаем, чего вы хотите. Здесь то же самое в стиле bashier, используя цикл for. См. Раздел Looping Constructs в справочном руководстве. Я также использую printf
вместо 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
Другая возможность - использовать ассоциативный массив:
#!/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
В зависимости от того, что вы хотите сделать, вы можете также рассмотреть эту вторую возможность. Но обратите внимание, что вам нелегко будет контролировать порядок, когда поля отображаются во второй возможности (ну, это ассоциативный массив, так что это не удивительно).
Ответ 2
Если все массивы упорядочены правильно, просто пройдите по индексу.
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
Ответ 3
Вам нужен цикл над массивом & 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
ОБНОВЛЕНИЕ: Не используйте приведенную ниже реализацию tr
. Это не будет работать для элементов массива, содержащих пробелы. Не удаляя его, чтобы комментарии оставались актуальными. См. комментарий Гленна Джекмана вместо ответа ниже.
/EDIT
Кроме того, вы можете использовать эту опцию (без цикла):
paste <(tr ' ' '\n' <<< ${array[*]}) <(tr ' ' '\n' <<< ${array2[*]}) | sed 's/\t/ is in /'
Ответ 4
Если две переменные были двумя строками с несколькими строками, вот так:
listA=$(echo -e "Vietnam\nGermany\nArgentina")
listB=$(echo -e "Asia\nEurope\nAmerica")
Тогда решение для этого случая:
while read strA <&3 && read strB <&4; do
echo "$strA is in $strB"
done 3<<<"$listA" 4<<<"$listB"
Ответ 5
Специально для заданного вопроса (массивы из 3 элементов):
for i in $(seq 0 2) ; do echo "${array1[$i]} is in ${array2[$i]}" ; done