tuneoの日記: シェル力を高める:teeの真価を知る 3
以前「一般ユーザがsudoを使ってスーパーユーザ権限でファイルに追記するには」みたいなお題や「複数ノードにsshで一括してデータを配るには」みたいなお題で使ったことはあったけど、今回やっとまともなtee使いの一歩を踏み出した気がする(大げさな
1年分のイベントをため込んでるでかいログファイルから直近半年分のログを抽出し、抽出したログからさらに直近3か月分、同様に直近1か月分、1週間分、1日分……という風にログを切り出していくという処理で、先だってこき下ろした、awkのまともな使い方も知らないバカが書いたbashスクリプトがご活躍していたと思ってくれ。以下のような感じだ。cut_*.shは、処理自体は同じなのに埋め込まれているパラメータだけが違うスクリプトの群れだ。殺意が沸くね!
sh cut_halfyear.sh < 1year.log > halfyear.log
sh cut_3months.sh < halfyear.log > 3month.log
sh cut_1month.sh < 3month.log > 1month.log
sh cut_1week.sh < 1month.log > 1week.log
sh cut_1day.sh < 1week.log > 1day.log
なぜか会社のえらいひとが軒並み大規模改修を嫌っている(まともに動かない排他制御を捨ててflock(1)でまともに動くロックを実装しただけで露骨に渋い顔をされた)ので、このログの切り出しも、こないだの日記で書いた「ほぼawkスクリプト」に置き換えるというアプローチをとりあえず断念することにして、みっともない一連の処理をどうにかできないか、と考えたわけだ。
何がみっともないって「ファイルを書いて」「ファイルを読む」が延々と続いているのが非常に気に食わない。いくらバッファリングされているとはいえ遅そうな感じがする。
というわけでteeを使ってこんな感じに仕立てた。
cat 1year.log |
sh cut_half_year.sh | tee halfyear.log |
sh cut_3months.sh | tee 3month.log |
sh cut_1month.sh | tee 1month.sh |
sh cut_1week.sh | tee 1week.sh |
sh cut_1day.sh > 1day.log
最初の1年分のログファイルを読み込んだら、あとは半年・3か月・1か月・1週間・1日分のファイルを書くだけ。最近のコンピュータは馬鹿みたいにメモリを積んでいるのでパイプを流れるデータが一時ファイルに書かれることはほぼないと思うし、昨今のマルチコアなCPUだとパイプラインの各ステージがそれぞれ別のコアで動いちゃったりして速そうな感じがする。ベンチマークは取ってないが高速化しているんじゃないかな?
しかし、こういうパイプラインを手で組むのは結構だるいな。支援してくれるナイスなツールとかないものだろうか。明日会社で調べてみよう。
sh で実行するのやめて…… (スコア:2)
#!/bin/bash と書いて bashスクリプト といいながら sh で実行するのやめて……。
svn-init() {
svnadmin create .svnrepo
svn checkout file://$PWD/.svnrepo .
}
Re:sh で実行するのやめて…… (スコア:1)
あー、そういやそうですね。他のところに気を取られてて気づきませんでした。直そう。
全部awk (スコア:1)
普通なら全部awkにやらせるかなあ。
リダイレクトは、awkの中でできるから。
awk 'NR>10{print $0 > "test.out"}'とかできるわけだし。
シェルスクリプト流用必須だと…?