LoginSignup
1
1

More than 1 year has passed since last update.

【csh】for文の代替方法(foreach + seq)

Posted at

まえおき

cshにはforeach文はあるけど、for文がありません。
感覚的にはforeach文の方が任意の配列をクロールしたりでfor文よりややこしそうなのに・・・(素人小並感)

というわけで、当記事ではcshでスクリプトを書く際にfor文の代替となる方法をご案内します。
たぶん知ってる人はやってるだろうし、すでに記事もあると思うんだけど、見つからなかったので投稿します。

結論から言おうッ!

例えば、1-31のループをしたいときは以下のように記載します。

csh.for
foreach i(`seq 1 31`)
    echo $i
end

解説

ザ・シンプルなので必要ないかもしれんけど一応説明します。

foreach

foreachは言わずと知れたループ文の一種です。
指定した配列の要素数分だけループするので、無限ループに陥る心配が少ないこと、結果が想像しやすいので、非常に使いやすいループ文ですね。

seq

次にseqは、連続した数字を出力するコマンドです。
ここだけ抽出します。

csh.seq
seq 1 31

今回の記載方法だと、第一引数が開始数、第二引数が終了数です。
ただ、開始数を省略した場合1スタートになるので
seq 31
でも全く問題ありません。
あくまでfor文らしく書くために開始数を記載しました。

普通に打ったらどうなるの

こうなります。

csh.seq
seq 31
1
2
3
..(中略)
29
30
31

cshは配列に代入した文字列をスペースかタブ、改行で区切る仕様となっています。
なのでseqコマンドとは非常に相性がいいです。使い勝手がほぼfor文です。

もっとfor文らしく

seqコマンドには以下のような機能もあります。

csh.for
seq 1 2 31
1
3
5
...(以下略)

開始数と終了数の間に数字を入れると、ステップ数を変更できます。
いやマジfor文に必要な機能じゃないすか。
迅悠一と風刃と中村悠一くらい相性いい。

中村悠一と杉田智和ほどには相性よくない。

オマケ

わかる人にはわかると思う用途例です。
利用してるソフトもわかるんじゃないでしょうか。

先月のログには、一日当たり何レコード記録されていたか、知りたい

csh
#!/bin/csh

set LogFile = `ログのフルパス`
set TargetDate = `date -d'1 month ago' + %Y/%m`
set LastDay = `date -d"$TargetDate/1 + 1 months + 1 days ago" +%d`

foreach i(`seq 1 $LastDay`)
    set SearchDay = `date -d"TargetDate/$i" "+$d $b"`
    cat $LogFile | grep "$SearchDay" | wc -l
end

おわりに

いろんなサイトみたけど、たいてい「cshでfor文書きたきゃwhile使え」って説明ばっかりだったんですよ。
なんか理由あるのかもしれないけど、while文は条件式ミスると無限ループに陥るし、インクリメントを別途明記しなきゃいかんしでいいことないので、これにしました。
可読性は間違いなくこちらのほうが高いと思うので、特別な理由がなければこれを使おうと思います。
お役立ていただければ幸いです。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1