まえおき
cshにはforeach文はあるけど、for文がありません。
感覚的にはforeach文の方が任意の配列をクロールしたりでfor文よりややこしそうなのに・・・(素人小並感)
というわけで、当記事ではcshでスクリプトを書く際にfor文の代替となる方法をご案内します。
たぶん知ってる人はやってるだろうし、すでに記事もあると思うんだけど、見つからなかったので投稿します。
結論から言おうッ!
例えば、1-31のループをしたいときは以下のように記載します。
foreach i(`seq 1 31`)
echo $i
end
解説
ザ・シンプルなので必要ないかもしれんけど一応説明します。
foreach
foreachは言わずと知れたループ文の一種です。
指定した配列の要素数分だけループするので、無限ループに陥る心配が少ないこと、結果が想像しやすいので、非常に使いやすいループ文ですね。
seq
次にseqは、連続した数字を出力するコマンドです。
ここだけ抽出します。
seq 1 31
今回の記載方法だと、第一引数が開始数、第二引数が終了数です。
ただ、開始数を省略した場合1スタートになるので
seq 31
でも全く問題ありません。
あくまでfor文らしく書くために開始数を記載しました。
普通に打ったらどうなるの
こうなります。
seq 31
1
2
3
..(中略)
29
30
31
cshは配列に代入した文字列をスペースかタブ、改行で区切る仕様となっています。
なのでseqコマンドとは非常に相性がいいです。使い勝手がほぼfor文です。
もっとfor文らしく
seqコマンドには以下のような機能もあります。
seq 1 2 31
1
3
5
...(以下略)
開始数と終了数の間に数字を入れると、ステップ数を変更できます。
いやマジfor文に必要な機能じゃないすか。
迅悠一と風刃と中村悠一くらい相性いい。
中村悠一と杉田智和ほどには相性よくない。
オマケ
わかる人にはわかると思う用途例です。
利用してるソフトもわかるんじゃないでしょうか。
先月のログには、一日当たり何レコード記録されていたか、知りたい
#!/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文は条件式ミスると無限ループに陥るし、インクリメントを別途明記しなきゃいかんしでいいことないので、これにしました。
可読性は間違いなくこちらのほうが高いと思うので、特別な理由がなければこれを使おうと思います。
お役立ていただければ幸いです。