배열이 있습니다
declare -a arr0=("'1 2 3'" "'4 5 6'")
그리고 변수
x=0
그런 다음 배열 이름으로 새 변수를 만듭니다.
tmp="arr$x"
arr0
이 변수의 내용을 다음과 같이 확장하고 싶습니다.tmp
newArr=( "${!tmp}" )
newArr
예를 들어 인덱싱 등을 사용하여 일반 배열처럼 사용됩니다.
하지만 지금 인쇄하려고 하면 다음과 같습니다.
$ echo ${newArr[@]}
'1 2 3'
첫 번째 요소만 저장되는데 어떻게 수정해야 할지 모르겠습니다.
newArr
저도 이렇게 만들어 보았습니다
newArr=( "${!tmp[@]}" )
하지만 더 나쁜 것은 0만 인쇄된다는 것입니다.
$ echo ${newArr[@]}
0
그렇다면 배열의 이름이 다른 변수에 저장되어 있는 경우 배열을 사용하는 방법을 알고 계시나요?
답변1
이것은 가능하다평가하다:
$ declare -a array=( 1 2 3 4 )
$ echo "${array[@]}"
1 2 3 4
$ p=ay
$ tmp=arr$p
$ echo "$tmp"
array
$ echo "\${${tmp}[@]}"
${array[@]}
$ echo "newarray=(\"\${${tmp}[@]}\")"
newarray=("${array[@]}")
$ eval "newarray=(\"\${${tmp}[@]}\")"
$ echo "${newarray[@]}"
1 2 3 4
$
echo로 시작하는 명령은 참조용일 뿐이며 eval은 위험합니다.
위의 내용은 희소 배열에 대한 배열 인덱스를 유지하지 않습니다.
답변2
간접 확장에는 몇 가지 예외가 있으며 배열에서 !를 사용하는 것은 예외 중 하나입니다.
남자 배쉬에서 :
매개변수의 첫 번째 문자가 느낌표(!)인 경우 1단계 변수 간접 지정이 도입됩니다. Bash는 나머지 인수로 구성된 변수 값을 변수 이름으로 사용합니다. 그런 다음 해당 변수를 확장하고 인수 자체의 값이 아닌 나머지 대체에 해당 값을 사용합니다. 이를 간접 확장이라고 합니다.
아래 설명된 ${!prefix*} 및 ${!name[@]}에 대한 확장은 예외입니다. ${!prefix*}는 접두사의 이름과 일치합니다. IFS 특수 변수의 첫 번째 문자로 구분된 이름이 접두사로 시작하는 변수 이름으로 확장됩니다.
에서 언급했듯이BASH 자주 묻는 질문 06, 한 가지 해결책은 다음과 같습니다.
arrA=("AA" "2" "4")
echo -e "array arrA contains: \c" && declare -p arrA
ref=arrA;
tmp=${ref}[@] #this can be adjusted to [1] , [2] etc to refer to particular array items
echo "Indirect Expansion Printing: ${!tmp}"
#Output
array arrA contains: declare -a arrA='([0]="AA" [1]="2" [2]="4")'
Indirect Expansion Printing: AA 2 4
답변3
bash
4.3에서는 유사한 nameref에 대한 지원이 추가되었습니다 ksh93
.
따라서 bash-4.3 이상에서는 다음을 수행할 수 있습니다.
a0[5]=whatever
x=0
typeset -n var="a$x"
printf '%s\n' "${var[5]}"
하지만 이는인용하다(포인터, 복사 아님) 변수에이름, 변수가 아님(함수의 지역 변수와 같이 서로 다른 컨텍스트에서 동일한 이름을 가진 여러 변수가 있는 경우 차이점이 중요합니다.)
bash
배열과 그 어색한 디자인을 복사합니다 ksh
. 배열을 복사하는 bash
것은 어렵습니다. 다음과 같은 도우미 기능을 사용할 수 있습니다.
copy_array() { # Args: <src_array_name> <dst_array_name>
eval '
local i
'"$2"'=()
for i in "${!'"$1"'[@]}"; do
'"$2"'[$i]=${'"$1"'[$i]}
done'
}
예를 들어 다음과 같이 사용됩니다.
$ a0[5]=123
$ x=0
$ copy_array "a$x" var
$ typeset -p var
declare -a var=([5]="123")
ksh
(그리고 bash
복사됨 ksh
)은 배열이 있는 유일한 쉘입니다.부족한(또는 키가 양의 정수로 제한되는 연관 배열) (또한 인덱스가 1 대신 0에서 시작하거나 직관적이지 않게 $array
요소로 확장되지 않고 인덱스 0으로 확장되는 유일한 배열). 다른 쉘을 사용하는 것이 훨씬 쉽습니다.
rc
:array_copy = $array
fish
:set array_copy = $array
csh
:set array_copy = ($array:q)
zsh
또는yash
:array_copy=("${array[@]}"}
간접 복사( $var
소스 배열 이름 포함)의 경우:
rc
:eval array_copy = '$'$var
fish
:eval set array_copy \$$var
csh
:eval "set array_copy = (\$${var}:q)"
zsh
:array_copy=("${(@P)var}")
yash
(또는zsh
):eval 'array_copy=("${'"$var"'[@]}")'