在bash中同时迭代两个数组

Posted

技术标签:

【中文标题】在bash中同时迭代两个数组【英文标题】:Iterate over two arrays simultaneously in bash 【发布时间】:2013-06-28 12:24:08 【问题描述】:

我有两个数组。

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

我想同时遍历这两个数组,即对两个数组的第一个元素调用一个命令,然后对第二个元素调用相同的命令,依此类推。伪代码:

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

我该怎么做?

【问题讨论】:

重复的***.com/questions/28725333/… 有一些想法,当值对不是两个并行数组,而是例如不同目录中的文件名对时。 【参考方案1】:

根据 anishsane 的回答和其中的 cmets,我们现在知道您想要什么。这是 bashier 样式中的相同内容,使用 for 循环。请参阅Looping Constructs section in the reference manual。我也在使用printf 而不是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

另一种可能性是使用关联数组:

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

根据你想做什么,你不妨考虑第二种可能性。但请注意,您不会轻易控制第二种可能性中字段的显示顺序(嗯,它是一个关联数组,所以这并不奇怪)。

【讨论】:

请不要将变量称为“数组”。曾经。为答案 +1。 有没有办法使用更易读的数组变量来实现这一点?变量 array 和 array2 在可读性方面是非常糟糕的做法 @ToiletGuy 使用您想要的名称。我重用了 OP 使用的名称【参考方案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

【讨论】:

有没有办法使用更易读的数组变量来实现这一点?就可读性而言,变量 array 和 array2 是非常糟糕的做法。如果我只想让数组为country 和array2 为continent 是的,变量名(就像所有变量名一样)是任意的。使用 Array 和 array2 是因为上面的问题是这样写的。【参考方案3】:

您需要对数组和数组2进行循环

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 的实现。它不适用于包含空格的数组元素。不删除它以保持 cmets 的相关性。请参阅格伦杰克曼的评论而不是下面的答案。

/编辑

或者,您可以使用此选项(不带循环):

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

【讨论】:

猜猜这就是你想要的。 @user2354862 如果是,你应该accept the answer。 或者,避免产生 tr 两次:paste &lt;(printf "%s\n" "$array[@]") &lt;(printf "%s\n" "$array2[@]") | sed 's/\t/ is in /'【参考方案4】:

如果这两个 vars 是两个多行的字符串,像这样:

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

【讨论】:

以上是关于在bash中同时迭代两个数组的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Bash 中迭代关联数组

迭代Java时从数组中删除对象

Vue:从数组中删除第一个元素并迭代它

是否可以在 jstl 中使用 foreach 同时迭代两个项目?

使用 *ngFor 迭代数组,同时过滤某个属性 [重复]

如何使用pytorch同时迭代两个数据加载器?