programing

배열을 인수로 Bash 함수에 전달하는 방법

closeapi 2023. 4. 16. 15:08
반응형

배열을 인수로 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

전술한 바와 같이 기능f2개의 인수를 수신합니다.첫 번째 인수는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"

이름 참조로 배열을 bash(버전 4.3+ 이후)의 함수에 전달하려면-n속성:

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

「 」를 참조해 주세요.nameref또는declare -nman 페이지에 있습니다.

먼저 "scalar" 값을 전달할 수 있습니다.이렇게 하면 작업이 간소화됩니다.

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

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

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

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

이 시점에서는 어레이와 같은 위치 파라미터를 직접 사용하는 것이 좋습니다.

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[@]}

이렇게 해봐

function parseArray {
    array=("$@")

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

array=("value" "value1")

parseArray "${array[@]}"

어레이를 함수로 전달

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

다음은 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

이 동작의 상세한 예와 설명은, 이 토픽의 긴 회답 「배열을 bash의 파라미터로서 전달」을 참조해 주세요.

어레이를 사용하여 json 파일을 만들고 jq를 사용하여 해당 json 파일을 구문 분석할 수도 있습니다.

예를 들어 다음과 같습니다.

my-array.json:

{
  "array": ["item1","item2"]
}

script.sh:

ARRAY=$(jq -r '."array"' $1 | tr -d '[],"')

그런 다음 스크립트를 호출합니다.

script.sh ./path-to-json/my-array.json

언급URL : https://stackoverflow.com/questions/16461656/how-to-pass-array-as-an-argument-to-a-function-in-bash

반응형