在bash中同时迭代两个数组

时间:2022-12-04 11:45:04

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?

我该怎么做呢?

3 个解决方案

#1


71  

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.

从anishsane的答案和评论中,我们现在知道你想要什么了。下面是bashier样式的相同内容,使用for循环。参见参考手册中的循环构造部分。我也用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

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).

取决于你想做什么,你不妨考虑第二个可能性。但是请注意,您不容易控制第二个可能性中显示的字段的顺序(好吧,这是一个关联数组,所以这并不奇怪)。

#2


15  

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

#3


12  

You need a loop over array & array2

需要对数组& 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

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

或者,您可以使用这个选项(没有循环):

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

#1


71  

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.

从anishsane的答案和评论中,我们现在知道你想要什么了。下面是bashier样式的相同内容,使用for循环。参见参考手册中的循环构造部分。我也用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

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).

取决于你想做什么,你不妨考虑第二个可能性。但是请注意,您不容易控制第二个可能性中显示的字段的顺序(好吧,这是一个关联数组,所以这并不奇怪)。

#2


15  

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

#3


12  

You need a loop over array & array2

需要对数组& 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

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

或者,您可以使用这个选项(没有循环):

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