将多个数组作为参数传递给函数内部的for循环

时间:2018-08-22 10:37:40

标签: bash

编辑:这已被标记为重复,所以让我解释一下这是如何独特的: 1.这用于循环 2.这应该可以在所有版本的bash中移植

first_array=(1 2 3)
second_array=(4 5 6)

do_stuff () {
_array1=( "$1" )
_array2=( "$2" )
for i in "${_array1[@]}"; do
  for i in "${_array2[@]}"; do
    echo "$i"
  done
done
}

do_stuff "$(echo ${first_array[@]})" "$(echo ${second_array[@]})"

这将输出:

4 5 6

代替:

4 
5 
6 
4 
5 
6 
4 
5 
6

为什么?如果我不将数组作为参数传递,则效果很好:

_array1=(1 2 3)
_array2=(4 5 6)

do_stuff () {
for i in "${_array1[@]}"; do
  for i in "${_array2[@]}"; do
    echo "$i"
  done
done
}

do_stuff

产生此输出:

4
5
6
4
5
6
4
5
6

我希望能够得到这个结果,但是传递我选择的不同数组,以避免重写类似的函数。

2 个答案:

答案 0 :(得分:2)

您的代码有什么问题

  1. echo ${first_array[@]}打印first_array的所有元素,并用空格隔开。由于您未引用数组扩展,因此它也将受到单词拆分和文件名扩展的影响!

  2. 命令替换"$(...)"将导致一个单字符串,这要归功于双引号并将字符串"1 2 3"传递给函数

    < / li>
  3. 然后,您将此单个字符串 "1 2 3"分配给数组_array1=( "$1" ),这将导致该数组仅包含一个元素

同样的事情也适用于第二个数组。将declare -p _array1 _array2添加到函数中,以查看两个数组确实仅包含一个字符串:

declare -a _array1=([0]="1 2 3")
declare -a _array2=([0]="4 5 6")

解决方法:

  1. 关注链接的问题:Passing arrays as parameters in bash

  2. 您有一个想法要传递所有要素。如果您只有一个阵列,那将很好地工作。然后,您可以使用arr=( "$@" )。但是,对于两个数组,问题是您不知道第一个数组有多少个元素。因此,您还需要传递第一个数组的元素数量:

    #!/usr/bin/env bash
    
    foo=(1 2 3)
    bar=(4 5 6)
    
    do_stuff() {
        local -a arr1=( "${@:2:$1}" ) arr2=( "${@:$1+2}" )
        declare -p arr1 arr2
    }
    
    do_stuff "${#foo[@]}" "${foo[@]}" "${bar[@]}"
    

此代码使用参数扩展,请参见Bash Reference Manual或这篇出色的wiki.bash-hackers.org文章。

答案 1 :(得分:1)

您可以尝试以下操作:

#!/bin/bash

first_array=(1 2 3)
second_array=(4 5 6)

do_stuff () {
    declare -a _array1=("${!1}")
    declare -a _array2=("${!2}")
    echo "${_array1[@]}"
    echo "${_array2[@]}"
}

do_stuff first_array[@] second_array[@]

输出:

$ ./script.sh
1 2 3
4 5 6