5でカウントアップするスクリプトを作成するにはどうすればよいですか?


10

私は非常に単純なbashスクリプトを作成して、375から3500(375、380、385 ...)の間の5の倍数をすべてリストしようとしていました。私が試したがうまくいかなかったのは:

for i in {375..3500}
do
        echo $i
        (($i += 5))
done

私はしばらくしてあきらめ、これをBASICで約15秒で書きました。

10 count = 375
20 print count
30 count = count+5
40 if count < 3500 then goto 20

BASICプログラムをbashスクリプトで作成するにはどうすればよいですか?


これはスタックオーバーフローの方が優れています。UnixとLinuxはOSではなくコーディングです。コーディングはスタックオーバーフロー用です。
noɥʇʎԀʎzɐɹƆ

回答:


20

あるいは、従来のCスタイルのforループを使用できます。

for ((i=375; i<=3500; i+=5)); do
    echo $i
done

これはおそらくseqを使用するより明確ではありませんが、サブプロセスを生成しません。私はCに慣れているので、これを理解するのは難しくありませんが、YMMVです。


1
この方法の欠点は、移植性が低いことです。seqメソッドはPOSIX shで機能します。
Wouter Verhelst 2015

ああ、POSIX shにはCスタイルのforループはありませんか?あなたは毎日何か新しいことを学びます...
Muzer

2
@WouterVerhelstさて、POSIX shに限定されている場合を除いて、GNU coreutilsの一部であるseqはおそらくありません。busyboxの実装はより限定的ですが、それ以外では、多くの組み込みシステムにはまったく実装されない可能性があります。
クリスダウン

1
@Muzer-少なくともdashそれをサポートしていません。@ChrisDown-「POSIX sh」「seqなし」を意味する必要がある理由はありません。しかし、ええ、当然ですが、seqがPOSIXで指定されていないという事実を見過ごしていました。
Wouter Verhelst 2015

27

とにかくブレース拡張を使用するので、その機能を十分に活用してください:

echo {375..3500..5}

このテクニックを使用して、のprintf代わりにを使用することによりecho、オプションのテキストを使用して各数値を別々の行に印刷することもできます。次に例を示します。

$ printf "Number %s is generated.\n" {375..3500..5}
Number 375 is generated.
Number 380 is generated.
Number 385 is generated.
...

編集する

コメントの@kojiroで指摘されているように、Mac OSはbash 3をデフォルトのシェルとして使用します。これは、ブレース展開のシーケンス式のインクリメントをサポートしていません。bashバージョン4にアップグレードするか、それをサポートする他のシェル(たとえば、最近のzsh)を使用する必要があります。


2
これはMac OS 10.10.3では動作しません。「{375..3500..5}」を出力します。
2015

6
@aswineだから、尋ねるときは常に OSについて言及するべきです。特にOSXには他のUNICEやLinuxと多くの違いがあるためです。
terdon

2
これ自体はOSの違いではありません。バージョンの違いです。OS XにはBASH 3 OOTBしかありません。今世紀のBASHは、ほとんどすべてのOS Xパッケージマネージャを使用してインストールできます。私はホームブリューを使います。
kojiro 2015

2
拡張が失敗するという事実は直接実行されますがbash -c、2つの異なるシェルが関与していることはほぼ保証されています。DOESは、$SHELL --versionそれはbashの3だと言いますか?
dhag

3
@mikeserv答えは非常に簡単bashです。この機能のどのバージョンが導入されたかがわからなかったので、私はそれを書きませんでした。小次郎のコメントから学んだ。そして、私とSCを比較しないでください。1970年後半以降のすべてのシェルの詳細と履歴はまったく知りません。もう一度考えてみてください。それを期待している場合は、反対票を投じてください。
jimmij

17

SEQ(1)の使用

for i in $(seq 375 5 3500)
do
    echo $i
done

または、単に:

seq 375 5 3500

4
さらに簡単なのは、ループを削除してを使用することseq 375 5 3500です。
dhag

11

次の2つの理由により、必要なforループスニペットが機能しませんでした。

  • (($i += 5))-ここで$iは、の値に展開されますi。したがって、展開はのようなものになり((375 += 5))、意味がありません(リテラル番号を別のリテラル番号に割り当てようとします)。これは通常((i += 5))$変数を展開しない)で達成されます
  • {375..3500}ループの最初の反復の前に展開されます。数字のリストになります375 376 ... 3499 3500。ループの反復iごとに、これらの番号のそれぞれに1つずつ割り当てられます。したがって、各反復の開始時に、iはそのリストの次の値に再割り当てされ、1ずつ増加します。((i += 5))事実上何もしません-iに5を追加しますが、その後、iは最初の開始時に再び再割り当てされます次の反復。

私はそのfor (( ; ; ))答えが一番好きだと思いますが、あなたに考えさせるためのいくつかの選択肢があります:


5の倍数を扱っており{a..b..i}、bashバージョン3.2.57(1)(OS Xの場合)では拡張がサポートされていないため、代わりにこれを少し難解なことができます。

for i in 375 {38..349}{0,5} 3500; do
    echo $i
done

これは、bashを使用してデカルト積を作成する方法を示しています。


一般的にはforループがこれを行うのに最も便利な方法だと思いますが、興味があれば、whileループ(BASICに少し近い)プログラムを使用できます。

count=375
while (( count <= 3500 )); do
    echo $count
    (( count += 5 ))
done

1
@jimmij ...デカルト積とは何ですか?必要に応じてコメントに反対票を投じることができ、私が言っても気にしません。私は興味がある。
mikeserv 2015

1
@mikeservコメントに反対投票することはできません:en.wikipedia.org/wiki/Cartesian_product
jimmij

@jimmij-よろしければ、私でも大丈夫です。
mikeserv 2015

@jimmij悪魔はあなたが話しているのですか?デカルト積は、2つのセット(同じセットである場合とそうでない場合がある)からの要素の可能なすべての組み合わせのタプルのセットです。もっと口語的には、2つのグループの「可能なすべての組み合わせ」です。1セットしか表示されません。ここにデカルト積はどのようにありますか?
jpmc26 2015

1
@ jpmc26正解です。「すべての可能な組み合わせ」なので、2つの軸をプロットできます。最初にから38までのすべての数値を書きます349。2番目にのみ2つの数字:05。今、それらのすべての組み合わせの順序対を作成することができます-あなたはセットとしてそれらを書くことができます{38,0}{38,5}... {349,5}、あるいは単に冗長シンボルを削除し{,そして}およびget ...新しい番号を380... 3495
jimmij

5

もちろん、そのためのアプリ(seq 375 5 3500)がありますが、コマンドラインからこれを行うにはさまざまな方法があります。最速かつ最も簡単な方法はを使用することだけseqですが、他のいくつかのオプションを次に示します。

for i in {375..3500}; do [[ (($i % 5)) -eq 0 ]] && echo $i; done

i=370; while [ $i -le 3500 ]; do printf "%s\n" $((i+=5)); done

perl -le '$i=shift;while($i<=$ARGV[0]){print $i; $i+=5; }' 375 3500
perl -le 'map{print $_ + 5} 370..3495'

awk 'BEGIN{ for(i=375;i<=3500;i+=5){print i}}'

Nit pick:$(($i % 5))書き込むことができます$((i % 5))
Gマンは「モニカを復活させる」と

4

POSIXly:

i=370
while [ 3500 -gt "$i" ]
do    echo "$((i+=5))"
done

...または...

echo 'for(x=370;x<=3500;x+=5)x' |bc

なぜ他の方法でやるのか分からない。もちろん、...

seq 375 5 3500

...またはdc

echo '370[5+pd3500>p]splpx'|dc

私はdcコードがどのように機能するかについて興味があります。確かにを使用するよりも興味深いですseq
dhag

1
@dhag-小さなループを書き込みます。それはsAVES [ストリング]の頂部にp、次いで、アレイlスタック及びEの上部に戻ってそれをOADS xがマクロとしてecutes。マクロ内5で、スタックをプッシュしてから上から2番目にポップ+し、両方のスタック値を合計で置き換えます。これは、pポップし、d先ほど作成したdupeの3500ときに、スタックにプッシュされる前にリントされて複製されます。比較>3500より大きい場合は、p配列に格納されている文字列(現在のマクロ)をマクロとしてロードして実行します。
mikeserv 2015

3

Bash 3で立ち往生している場合:

echo {375..3500} | tr ' ' '\n' | sed -n 'p;n;n;n;n'

必要に応じてawk

echo {375..3500} | tr ' ' '\n' | awk '!((NR-1)%5)'

ブレースの拡張については知りませんでした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.