zsh에서 배열 인덱스를 반복하는 방법은 무엇입니까?

zsh에서 배열 인덱스를 반복하는 방법은 무엇입니까?

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
%

관련 정보