在bash中同时迭代两个数组


80

我有两个数组。

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

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

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

我怎样才能做到这一点?

Answers:


98

现在,从阿尼桑的回答和其中的评论,我们知道您想要什么。这是bashier风格的同一件事,使用for循环。请参见参考手册中的循环构造”部分。我也用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

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


43

如果所有数组的顺序正确,只需传递索引即可。

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

18

您需要循环遍历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

编辑:不要使用下面的tr基于实现。它不适用于包含空格的数组元素。不要删除它,以保持评论的相关性。请参阅glenn jackman的评论,而不是下面的答案。

/编辑

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

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

3
这就是你想要的。
anishsane

@ user2354862如果是,则应该接受答案
Ansgar Wiechers

3
或者,避免两次生成tr:paste <(printf "%s\n" "${array[@]}") <(printf "%s\n" "${array2[@]}") | sed 's/\t/ is in /'
glenn jackman 2014年

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"

它们已经在两个数组中,无需将它们转换为字符串。
runlevel0

2

专门针对所问的问题(包含3个项目的数组):

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


0
#!/bin/bash

read -p "Enter File name : " file

read -ra USERS <<< $(cut -d: -f1 ${file})
read -ra DIRS <<< $(cut -d: -f6 ${file})


if [ ${#USERS[@]} == ${#DIRS[@]} ]
then

echo "Same size arrays.."

THRO=$(expr ${#USERS[@]} - 1)

for i in `seq 0 ${THRO}`
do
useradd -G sftp_users -d /home/sftp${DIRS[$i]} -s /sbin/nologin ${USERS[$i]}
done


else

echo "need same size arrays.."

fi

对我来说,类似的东西起作用。我试图从另一台服务器的/ etc / passwd文件创建多个用户。不是通用的解决方案,但达到了目的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.