zsh 및 bash의 루프


57

zsh 에서 루프를 작성하는 두 가지 대체 방법이 있습니다 .

  1. for x (1 2 3); do echo $x; done
  2. for x in 1 2 3; do echo $x; done

둘 다 인쇄합니다.

1
2
3

내 질문은 왜 두 가지 구문입니까? 되어 $x다른 통해 반복 객체의 유형 그들 각각에?

않습니다 배쉬는 비슷한 구분을?

추가:

다음은 왜 작동합니까?

#!/bin/zsh
a=1
b=2
c=5    

d=(a b c)    
for x in $d; do print $x;done

그러나 이것은 그렇지 않습니까? :

#!/bin/zsh
a=1
b=2
c=5

d=(a b c)    
# It complains with "parse error near `$d'"
for x $d; do print $x;done 

5
루프에 대한 csh 스타일 인 "작동하지 않음"의 예 에서는 괄호가 없습니다. for x ($d); do print $x; done작동하고 질문의 시작 부분에 열거 한 첫 번째 구문과 일치합니다.
팀 케네디

1
이 두 진술이 실제로 "동일하게"작동하지 않는다는 것은 매우 미쳤다 . 말 그대로 머리를 감쌀 수 없습니다! 나는 그 당시 쉘 디자이너들이 담배를 피우는 담배를 피워야한다.
alex grey

조심스럽게,이 이야기에는 처음 등장한 것보다 더 많은 것이 있습니다. 나는 당신이 내 대답을 확인하도록 초대합니다.
jasonleonhard

다른 사람이 언급하지는 않았지만 두 가지 형식 모두 do / done을 생략 할 수 있습니다 : for i ({0..4..2}) for j ({a..c}) echo "($i,$j)"= {0,2,4}x{a,b,c}. 세미콜론은 가장 바깥 쪽 루프에 적용되고 리디렉션은 가장 안쪽에 적용되며이를 변경해야하는 경우 중괄호 만 필요합니다 : for i ({0..4..2}) { for j ({a..c}) echo "($i,$j)" } | cat -n= {1,...,9}*({0,2,4}x{a,b,c}). 물론 루프를 zsh 확장과 결합 할 수 있습니다.for i ("("{0..4..2}","{a..c}")") echo $i
John P

답변:


58

루프와 같은 여러 형태의 복잡한 명령 은 zsh에서 대체 형태 를 갖습니다 . 이러한 형태는 주로 C 쉘 에서 영감을 받았는데, zsh는 어렸을 때 사라졌지 만 이제는 사라졌습니다. 이 대체 양식은 일반 양식과 똑같이 작동하며 다른 구문 일뿐입니다. 약간 짧지 만 명확하지 않습니다.

for명령 의 표준 형식 은 for x in 1 2 3; do echo $x; done이고 명령 의 표준 형식 whilewhile test …; do somecommand; done입니다. Ksh, bash 및 zsh는 대체 형식 인 for: for ((i = 0; i < 42; i++)); do somecommand; done을 사용하여 forPascal 또는 C와 같은 언어 의 루프 를 모방하여 정수를 열거합니다. zsh에 존재하는 다른 이국적인 형식은 zsh에만 적용되지만 종종 csh에서 영감을 얻습니다.


감사합니다 @Guilles. 그래도 여전히 조금 혼란 스럽습니다. 특정 형태는 zsh무엇입니까? 또한 OP의 끝에 구문 사이의 번역 방법을 알 수없는 예제를 추가했습니다. 차이점이 단지 구문 인 경우, 부록에서 두 번째 스크립트를 수정하여 작동 시키려면 어떻게해야합니까?
Amelio Vazquez-Reina

3
@intrpc 업데이트 된 답변보기. 마지막 예제 for x $d와 같이 , 당신이 쓴 zz는 당신이 쓴 곳 in이나 (어디를 기대 하기 때문에 작동하지 않습니다 $d. 문장 부호와 예약어는 변수 확장에서 올 수 없으며 변수 확장에서 셸을 시작하기 전에 구문 분석해야합니다.
Gilles

@intrpc는 모두 zsh에 따라 다릅니다. zsh는 bourne, korn 및 c-shell 구문을 모두 지원하도록 특별히 설계되었습니다.
팀 케네디

1
@pseyfert 그것은 작동하지만, 내가 보여주는 양식에 비해 이점이 없습니다 : 양식보다 이식성이 적고 for (( … ))3이 크면 많은 메모리를 사용합니다.
Gilles

1
@ alpha_989 sh와 같은 구문에서는 doafter 가 필요합니다 ));. zsh을 또 다른 구문 받아들이는 하나의 명령입니다. 그것이 그것을 받아들이는 이유 입니다. 이 후, 끝 이 없기 때문에 불평 합니다. 매뉴얼의 "복잡한 명령의 대체 양식"을 참조하십시오 . for ((…)); COMMANDCOMMANDfor ((i = 1; i<100; i++)); ghi show $i | grep "log"donedo
Gilles
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.