Bash에서 동적으로 배열을 생성하고 변수를 배열 이름으로 사용합니다.

Bash에서 동적으로 배열을 생성하고 변수를 배열 이름으로 사용합니다.

이 질문은 여러 번 요청되었지만 어떤 방법도 효과가 없었습니다. 변수에서 배열 이름을 가져온 배열을 동적으로 만들고 싶습니다. 이제 배열부터 시작하겠습니다.

#!/bin/bash
i="aaa"
eval ${i}=("1")

밝혀지다

./1.sh: line 3: syntax error near unexpected token `('
./1.sh: line 3: `eval ${i}=("1")'

다음과 같은 결과:

$(eval ${i})=('1')
$(eval echo ${i})=('1')
$(eval "echo ${i}")=('1')

모든 것을 평가하고 싶지 않고 배열 이름만 평가하고 싶습니다. 가능하다면 eval을 완전히 사용하는 것을 피하고 싶습니다.

답변1

eval인수로 문자열이 필요합니다. 따옴표 없이는 사용할 수 없으며 (셸에서 특별한 의미를 갖습니다.

i=aaa
eval "$i=(1 2)"  # Use a string, $i will expand in double quotes.
echo ${aaa[1]}

declare또는 typeset대신 다음을 사용할 수도 있습니다 eval.

declare -a $i='(1 2)'

여전히 괄호와 공백을 인용해야 합니다.

이를 완전히 방지 하려면 eval값을 하나씩 할당하면 됩니다.

#! /bin/bash
name=aaa
values=(1 2)
for ((i=0; i<${#values[@]}; ++i)) ; do
    read "$name[$i]" <<< "${values[i]}"
done
echo ${aaa[1]}

답변2

를 사용하지 않고 배열을 로드하는 방법은 다음과 같습니다 eval. 구문을 사용하지 않고 ( data )대신 입력 문자열과 선택한 구분 기호를 사용합니다. 예제에서는 다음을 사용합니다.|

i=aaa
IFS='|' read -a "$i" <<<"1|2   with spaces"
printf '%s\n' "${aaa[@]}"

산출:

1
2   with spaces

답변3

declare동적 이름과 값, 변수 간접 참조를 사용하여 해당 이름을 기반으로 변수를 참조할 수 있습니다 . printf '%q'동적 할당 중에 값을 사용할 수 있도록 "쉘 이스케이프" 값을 도울 수 있습니다.

#!/bin/bash
declare -a products=( phone computer )
printf 'Product: %s\n' "${products[@]}"
# Product: phone
# Product: computer
unset products

declare varName='products'
declare -a "${varName}"='( cell\ phone laptop\ computer )'
declare arrayRef="${varName}[@]"
printf 'Product: %s\n' "${!arrayRef}"
# Product: cell phone
# Product: laptop computer
unset "${varName}"

declare -a toCopy=( 'LED TV' '"Smart" car' )
declare -a "${varName}"="( $( printf '%q ' "${toCopy[@]}" ) )"
printf 'Product: %s\n' "${!arrayRef}"
# Product: LED TV
# Product: "Smart" car
unset "${varName}"

관련 정보