zshおよびbashのforループ


57

zshでループを作成する2つの代替方法があることに気付きました。

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

それらは両方とも印刷します:

1
2
3

私の質問は、なぜ2つの構文ですか?さ$xの異なる繰り返し処理対象物の種類、それらのそれぞれに?

bashは同様の区別を作りますか?

補遺:

なぜ次のように機能しますか?:

#!/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
それはSO狂気 -これらの二つの文があること-実際に両方「同じ仕事」しません。私は文字通りそれを回避できません!シェルデザイナーが喫煙していたものを喫煙する必要があります」
アレックスグレー

注意してください、この物語には最初に現れる以上のものがあります。私の答えを確認してください。
ジェイソンレオンハルト

私は他の誰もそれを言及するのを見ませんでしたが、両方の形式は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
ジョン・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の最後に1つの例を追加しましたが、構文間の変換方法がわかりません。違いが単なる構文である場合、補遺の2番目のスクリプトを修正して機能させるにはどうすればよいですか?
アメリオバスケスレイナ

3
@intrpc更新された回答を参照してください。あなたの最後の例に関しては、あなたが書いたのでfor x $d、zshはあなたが書いたかのどちらかinまたは(場所を期待しているので機能しません$d。句読点と予約語は変数展開から来ることはできません。シェルが変数展開を開始する前にそれらを解析する必要があります。
ジル 'SO-悪であるのをやめる'

@intrpcは両方ともzsh固有です。zshは、3つすべてのハイブリッドであるため、bourne、korn、およびc-shell構文の両方をサポートするように特別に設計されました。
ティムケネディ

1
@pseyfert動作しますが、ここで示すフォームよりも利点はありません。for (( … ))フォームよりも移植性が低く、3が大きい場合は大量のメモリを使用します。
ジル 'SO-悪であるのをやめる'

1
@ alpha_989 shのような構文では、doafter が必要));です。Zsh は、単一のコマンドfor ((…)); COMMANDCOMMANDある別の構文も受け入れます。それがを受け入れる理由for ((i = 1; i<100; i++)); ghi show $i | grep "log"です。doneこの後見ると、do終了することがなかったので文句を言います。マニュアルの「複雑なコマンドの代替形式」を参照してください。
ジル 'SO-悪であるのをやめる'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.