나는 "Bash Pocket Reference" 책을 읽고 연관 배열에 관한 섹션을 읽었습니다. 이제 책에 있는 샘플 코드를 시험해 보니 예상치 못한 답을 얻었습니다.
istanev@inspiron5559:~$ data=([joe]=30 [mary]=25)
istanev@inspiron5559:~$ echo ${data[joe]}
25
istanev@inspiron5559:~$ echo ${data[mary]}
25
data[joe]가 30을 반환하면 안 되나요? 왜 25를 반환합니까? 내 bash 버전은 4.3.46(1) 릴리스입니다.
답변1
기본적으로 bash는 배열을 인덱스 배열로 처리합니다.
이 경우 인덱스는 산술 표현식으로 평가됩니다.
$ joe=3 mary=6
$ unset data
$ data=([joe]=111 [mary]=bbb)
$ declare -p data
declare -a data=([3]="111" [6]="bbb")
출력에는 다음과 같은 몇 가지 사항이 표시됩니다.
- 배열은
-a
출력에서 인덱싱됩니다. - 배열에는 두 개의 값이 포함되어 있습니다.
joe
값의 인덱스는 변수 sum 의 숫자 값과 일치합니다mary
.- 배열에 포함된 값은 문자열일 수 있습니다.
이는 인덱스가 인용된 경우에도 마찬가지입니다(작은따옴표라도).
$ joe=3 mary=6
$ unset data
$ data=(["joe"]=111 ["mary"]=bbb)
$ declare -p data
declare -a data=([3]="111" [6]="bbb")
인덱스로 사용되는 문자열이 숫자를 포함하도록 정의되지 않은 경우 어쨌든 값이 0인 산술 표현식으로 평가됩니다.
$ unset joe ; unset mary ; unset data
$ data=([joe]=111 [mary]=bbb)
$ declare -p data
declare -a data=([0]="bbb")
[joe]=111
평가 결과는 이고 [0]=111
인덱스의 배열 0
은 로 설정 됩니다 111
. 그러나 으로 [mary]=bbb
평가되어 [0]=bbb
index의 배열 값이 로 대체 0
됩니다 bbb
.
실제로 연관 배열을 가지려면 사용하기 전에 정의해야 합니다.
데이터가 포함되어 있는 동안에는 변경할 수 없습니다. 배열 설정은 다음과 같습니다.
$ declare -A data
bash: declare: data: cannot convert indexed to associative array
하지만 이를 지우려면 다음을 수행할 수 있습니다.
$ joe=3 ; mary=6 ; unset data
$ declare -A data
$ data=([joe]=111 [mary]=bbb)
$ declare -p data
declare -A data=([joe]="111" [mary]="bbb" )
보시다시피 인덱스로 사용되는 문자열도 유효한 변수 이름이며 값이 포함되어 있는지는 중요하지 않습니다. 연관 배열의 문자열 인덱스로 사용됩니다.
답변2
typeset -A
연관 배열은 또는 이에 상응하는( declare -A
또는 readonly -A
bash에서)을 사용하여 명시적으로 선언해야 합니다 . 기본적으로 배열은 정수 인덱스가 있는 "일반" 배열입니다. 정수 인덱스 배열의 숫자가 아닌 인덱스는 산술 표현식으로 해석되고, 산술 표현식에서 설정되지 않은 변수 이름은 기본적으로 0으로 해석되므로 data=([joe]=30 [mary]=25)
set data[0]=30
, then data[0]=25
및 ${data[whatever]}
is 요소는 0, 즉 입니다 25
.
bash-4.3$ indexed=([a]=aye [b]=bee [x+1]=cee)
bash-4.3$ echo length=${#indexed[@]} a=${indexed[a]} b=${indexed[b]} x+1=${indexed[x+1]} 1=${indexed[1]}
length=2 a=bee b=bee x+1=cee 1=cee
bash-4.3$ typeset -A associative=([a]=aye [b]=bee [x+1]=cee)
bash-4.3$ echo length=${#associative[@]} a=${associative[a]} b=${associative[b]} x+1=${associative[x+1]} 1=${associative[1]}
length=3 a=aye b=bee x+1=cee 1=
왜냐하면 indexed
은 숫자 인덱스가 있는 배열이고 , indexed[a]
및 는 indexed[b]
모두 이기 때문입니다 . 연관 배열의 경우 대괄호 안에 있는 내용이 문자열로 구문 분석됩니다(일반적으로 큰따옴표로 확장되므로 로 쓸 수 있음 ).indexed[0]
indexed[x+1]
indexed[1]
${associative[$key]}