Bash에서는 다음과 같이 배열의 인덱스를 반복할 수 있습니다.
~$ for i in "${!test[@]}"; do echo $i; done
여기서 test는 배열입니다. 예를 들어
~$ test=(a "b c d" e f)
그래서 출력은 다음과 같습니다
0
1
2
3
그러나 zsh에서 동일한 작업을 수행하면 오류가 발생합니다.
➜ ~ for i in "${!test[@]}"; do echo $i; done
zsh: event not found: test[@]
무슨 일이야?
zsh에서 인덱스를 반복하는 올바른 방법은 무엇입니까?
답변1
zsh
배열은 대부분의 다른 쉘 및 언어의 배열과 같은 일반 배열이며, 키가 양의 정수(희소 배열이라고도 함)로 제한된다는 점에서 ksh/bash의 연관 배열과 다릅니다. zsh
연관 배열에는 별도의 변수 유형이 있습니다(키는 0바이트 이상의 임의 시퀀스입니다).
따라서 일반 배열의 인덱스는 항상 1부터 배열 크기까지의 정수입니다(ksh 호환성이 활성화되지 않은 경우 배열 인덱스는 1 대신 0부터 시작합니다).
그래서:
typeset -a array
array=(a 'b c' '')
for ((i = 1; i <= $#array; i++)) print -r -- $array[i]
그러나 일반적으로 인덱스가 아닌 배열 멤버를 반복합니다.
for i ("$array[@]") print -r -- $i
(이 "$array[@]"
구문은 반대 $array
이며 빈 요소를 유지합니다.)
또는:
print -rC1 -- "$array[@]"
모든 요소를 명령에 전달합니다.
이제 루프를 반복하세요.연관 배열, 구문은 다음과 같습니다
typeset -A hash
hash=(
key1 value1
key2 value2
'' empty
empty ''
)
for key ("${(@k)hash}") printf 'key=%s value=%s\n' "$key" "$hash[$key]"
( @
빈 요소를 보존하려면 내부 따옴표를 다시 사용하십시오).
다음을 사용하여 키와 값을 명령에 전달할 수도 있습니다.
printf 'key=%s value=%s\n' "${(@kv)hash}"
Bourne형 셸의 다양한 배열 설계에 대한 자세한 내용은 다음을 참조하세요.어레이에 대한 테스트 셸 지원
답변2
이 기사에서 말하듯이Z-Shell 사용자 가이드 - 5장: 교체:
이는 다음을 통해 다른 매개변수로 확장될 수 있습니다.
% array=(one two three)
% print -l "${array[@]}"
one
two
three
더 일반적으로는 다른 플래그(@)를 사용하는 모든 형태의 대체에 대해 다음과 같습니다.
% print -l "${(@)array}"
one
two
three
그렇다면 두 번째 접근 방식을 시도해 볼까요?
답변3
중괄호를 사용하면 다음과 같습니다 { }
.
% test=(a "b c d" e f)
% for i in {1..$#test}; do echo $i; done
1
2
3
4
%