연관 배열에서 잘못된 값을 검색했습니까?

연관 배열에서 잘못된 값을 검색했습니까?

나는 "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]=bbbindex의 배열 값이 로 대체 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 -Abash에서)을 사용하여 명시적으로 선언해야 합니다 . 기본적으로 배열은 정수 인덱스가 있는 "일반" 배열입니다. 정수 인덱스 배열의 숫자가 아닌 인덱스는 산술 표현식으로 해석되고, 산술 표현식에서 설정되지 않은 변수 이름은 기본적으로 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]}

관련 정보