joinコマンド便利
存在は知っていたが使うことはほとんどなかったjoinを最近使うようになってコレ便利ってなってます。
textファイルに対してSQLのInner join、Outer joinみたいなことができます。
バッチログの開始時間と終了時間を一覧化する。
この記事はバッチログ群に対してgrepしてjoinすることで、このログに含まれる開始時刻と終了時刻を抽出して最終的にはExcelに放り込んでみて便利だなーとなったのでその記録です。
今回のバッチログ群は執筆者がプロジェクトで見た感じのログを擬似的に再現したものです。
ログの例
以下みたいなのが各JOBごとにいっぱい出る環境を相手にしてます。
JOBIDをファイル名に含み、開始と終了の行にはgrepで抜くのにちょうどいい文字列と行出力時の時間を含んでいます。
2015/07/19 23:59:20 start
hogehoge
fugafuga
piyopiyo
2015/07/20 00:20:30 end
2015/07/20 01:20:30 start
foo
var
baz
2015/07/20 01:25:35 end
こういったファイル群から、ファイル名とjob開始時間、job終了時間を1行にまとめるために、コマンドをいろいろ叩きます。
開始時間と終了時間をgrep
開始と終了の時間を抜きます。
grepで抜くことによって、ファイル名(JOB名)とタイムスタンプを含む出力がでます。
$ fgrep start *
jobA.log:2015/07/19 23:59:20 start
jobB.log:2015/07/20 01:20:30 start
$ fgrep end * > ended.txt
jobA.log:2015/07/20 00:20:30 end
jobB.log:2015/07/20 01:25:35 end
️ファイル名でJOINしたい
上記の2つの出力をファイルにした後ファイル名でjoinしてくれれば目的達成なのですが問題がありました。
1現場で唯一つかえる*nix環境のAIXに存在したjoinコマンドはデリミタが指定できないようだったので、joinコマンドの標準のデリミタであるスペースかタブにしないと正しくjoinできません。
joinのキーが"ファイル名:出力年月日"という微妙きわまりない状態になります。
すみませんちゃんとあったので、オプションでやる場合、他の記事等参照してみてください
そのため、ファイル名の後ろに出力されるコロンが邪魔なので、sedで"log:"を"log "と置換してコロンの存在をごまかします。
$ fgrep start * |sed -e 's/log:/log /g'
jobA.log 2015/07/19 23:59:20 start
jobB.log 2015/07/20 01:20:30 start
$ fgrep start * |sed -e 's/log:/log /g' > started.txt
$ fgrep end * |sed -e 's/log:/log /g'
jobA.log 2015/07/20 00:20:30 end
jobB.log 2015/07/20 01:25:35 end
$ fgrep end * |sed -e 's/log:/log /g' > ended.txt
ファイル名の後ろがスペースになりました。
そしてjoin
ここまで下処理をして、joinが可能になります。
joinコマンドは入力ファイルのソートが必要らしいですがgrepの時点でファイル名によってソートされてるようなので省略。
$ join started.txt ended.txt
jobA.log 2015/07/19 23:59:20 start 2015/07/20 00:20:30 end
jobB.log 2015/07/20 01:20:30 start 2015/07/20 01:25:35 end
これでファイル名(JOBID)と開始時間と終了時間が1行に出力されました。
このファイルをExcelに放り込めるように更に正規表現などをかけますがそこは略。
Excelに取り込むことで開始時間、終了時間の列挙、処理時間が一覧化できました。
コマンドで作ることで、サクッと間違いなく作れるのがよいです。