簡體   English   中英

如何將數組作為參數傳遞給 Bash 中的函數

[英]How to pass array as an argument to a function in Bash

眾所周知,在 bash 編程中,傳遞參數的方式是$1 , ..., $N 但是,我發現將數組作為參數傳遞給接收多個參數的函數並不容易。 這是一個例子:

f(){
 x=($1)
 y=$2

 for i in "${x[@]}"
 do
  echo $i
 done
 ....
}

a=("jfaldsj jflajds" "LAST")
b=NOEFLDJF

f "${a[@]}" $b
f "${a[*]}" $b

如上所述,函數f接收兩個參數:第一個分配給x ,它是一個數組,第二個分配給y

f可以通過兩種方式調用。 第一種方式使用"${a[@]}"作為第一個參數,結果是:

jfaldsj 
jflajds

第二種方式使用"${a[*]}"作為第一個參數,結果是:

jfaldsj 
jflajds 
LAST

結果都不如我所願。 那么,有沒有人知道如何在函數之間正確傳遞數組?

你不能傳遞一個數組,你只能傳遞它的元素(即擴展數組)。

#!/bin/bash
function f() {
    a=("$@")
    ((last_idx=${#a[@]} - 1))
    b=${a[last_idx]}
    unset a[last_idx]

    for i in "${a[@]}" ; do
        echo "$i"
    done
    echo "b: $b"
}

x=("one two" "LAST")
b='even more'

f "${x[@]}" "$b"
echo ===============
f "${x[*]}" "$b"

另一種可能性是按名稱傳遞數組:

#!/bin/bash
function f() {
    name=$1[@]
    b=$2
    a=("${!name}")

    for i in "${a[@]}" ; do
        echo "$i"
    done
    echo "b: $b"
}

x=("one two" "LAST")
b='even more'

f x "$b"

您可以通過設置-n屬性將數組按名稱引用傳遞給 bash(自 4.3+ 版起)中的函數:

show_value () # array index
{
    local -n myarray=$1
    local idx=$2
    echo "${myarray[$idx]}"
}

這適用於索引數組:

$ shadock=(ga bu zo meu)
$ show_value shadock 2
zo

它也適用於關聯數組:

$ declare -A days=([monday]=eggs [tuesday]=bread [sunday]=jam)
$ show_value days sunday
jam

另請參見手冊頁中的namerefdeclare -n

您可以先傳遞“標量”值。 這將簡化事情:

f(){
  b=$1
  shift
  a=("$@")

  for i in "${a[@]}"
  do
    echo $i
  done
  ....
}

a=("jfaldsj jflajds" "LAST")
b=NOEFLDJF

f "$b" "${a[@]}"

此時,你不妨直接使用array-ish的位置參數

f(){
  b=$1
  shift

  for i in "$@"   # or simply "for i; do"
  do
    echo $i
  done
  ....
}

f "$b" "${a[@]}"

這將解決將數組傳遞給函數的問題:

#!/bin/bash

foo() {
    string=$1
    array=($@)
    echo "array is ${array[@]}"
    echo "array is ${array[1]}"
    return
}
array=( one two three )
foo ${array[@]}
colors=( red green blue )
foo ${colors[@]}

將數組作為函數傳遞

array() {
    echo "apple pear"
}

printArray() {
    local argArray="${1}"
    local array=($($argArray)) # where the magic happens. careful of the surrounding brackets.
    for arrElement in "${array[@]}"; do
        echo "${arrElement}"
    done

}

printArray array

像這樣試試

function parseArray {
    array=("$@")

    for data in "${array[@]}"
    do
        echo ${data}
    done
}

array=("value" "value1")

parseArray "${array[@]}"

這是一個示例,其中我將 2 個 bash 數組接收到一個函數中,以及它們之后的附加參數。 對於任意數量的 bash 數組任意數量的附加參數,只要每個 bash 數組的長度恰好位於該數組的元素之前,這種模式就可以無限期地繼續下去,以適應任何輸入參數順序

print_two_arrays_plus_extra_args的函數定義:

# Print all elements of a bash array.
# General form:
#       print_one_array array1
# Example usage:
#       print_one_array "${array1[@]}"
print_one_array() {
    for element in "$@"; do
        printf "    %s\n" "$element"
    done
}

# Print all elements of two bash arrays, plus two extra args at the end.
# General form (notice length MUST come before the array in order
# to be able to parse the args!):
#       print_two_arrays_plus_extra_args array1_len array1 array2_len array2 \
#       extra_arg1 extra_arg2
# Example usage:
#       print_two_arrays_plus_extra_args "${#array1[@]}" "${array1[@]}" \
#       "${#array2[@]}" "${array2[@]}" "hello" "world"
print_two_arrays_plus_extra_args() {
    i=1

    # Read array1_len into a variable
    array1_len="${@:$i:1}"
    ((i++))
    # Read array1 into a new array
    array1=("${@:$i:$array1_len}")
    ((i += $array1_len))

    # Read array2_len into a variable
    array2_len="${@:$i:1}"
    ((i++))
    # Read array2 into a new array
    array2=("${@:$i:$array2_len}")
    ((i += $array2_len))

    # You can now read the extra arguments all at once and gather them into a
    # new array like this:
    extra_args_array=("${@:$i}")

    # OR you can read the extra arguments individually into their own variables
    # one-by-one like this
    extra_arg1="${@:$i:1}"
    ((i++))
    extra_arg2="${@:$i:1}"
    ((i++))

    # Print the output
    echo "array1:"
    print_one_array "${array1[@]}"
    echo "array2:"
    print_one_array "${array2[@]}"
    echo "extra_arg1 = $extra_arg1"
    echo "extra_arg2 = $extra_arg2"
    echo "extra_args_array:"
    print_one_array "${extra_args_array[@]}"
}

示例用法:

array1=()
array1+=("one")
array1+=("two")
array1+=("three")

array2=("four" "five" "six" "seven" "eight")

echo "Printing array1 and array2 plus some extra args"
# Note that `"${#array1[@]}"` is the array length (number of elements
# in the array), and `"${array1[@]}"` is the array (all of the elements
# in the array) 
print_two_arrays_plus_extra_args "${#array1[@]}" "${array1[@]}" \
"${#array2[@]}" "${array2[@]}" "hello" "world"

示例輸出:

Printing array1 and array2 plus some extra args
array1:
    one
    two
    three
array2:
    four
    five
    six
    seven
    eight
extra_arg1 = hello
extra_arg2 = world
extra_args_array:
    hello
    world

有關其工作原理的更多示例和詳細說明,請在此處查看我對此主題的更長回答: Passing arrays as parameters in bash

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM