【shell】lotateされたログ毎にgrepでヒットした件数をまとめて表示する


経緯

ログからエラーの件数を数える際に、lotateされたログファイルをいちいち一個ずつ見ていくのがだるい。
ファイル名に日付がつくという性質上、サジェストしても最後までファイル名が確定しないのが特に辛い。
仕事をしてて結構な回数この作業をやっているなと思い、重い腰を上げてまとめて出せるようにしようと決意した。

以下、/path/toというディレクトリにログファイルと、lotateされたログファイルが一緒に入っている、という前提で進めていく。

結論

コマンド

find /path/to -type f -name "hogehoge.com.ssl.access.log*" | xargs zgrep -wc {{調べたい文字列}} | sort

出力

/path/to/hogehoge.com.ssl.access.log-20180825.gz:273
/path/to/hogehoge.com.ssl.access.log-20180826.gz:231
/path/to/hogehoge.com.ssl.access.log-20180827.gz:239
/path/to/hogehoge.com.ssl.access.log-20180828.gz:280
/path/to/hogehoge.com.ssl.access.log-20180829.gz:337
/path/to/hogehoge.com.ssl.access.log-20180830.gz:284
/path/to/hogehoge.com.ssl.access.log-20180831.gz:298
/path/to/hogehoge.com.ssl.access.log-20180901.gz:318
/path/to/hogehoge.com.ssl.access.log-20180902.gz:288
/path/to/hogehoge.com.ssl.access.log-20180903.gz:298
/path/to/hogehoge.com.ssl.access.log:254

何をしているか

find

/path/toの場所にある、前方一致で"hogehoge.com.ssl.access.log"という名前を含むファイルを検索している。
find部分のみの結果は以下のようになる。

/path/to/hogehoge.com.ssl.access.log
/path/to/hogehoge.com.ssl.access.log-20180831.gz
/path/to/hogehoge.com.ssl.access.log-20180828.gz
/path/to/hogehoge.com.ssl.access.log-20180829.gz
/path/to/hogehoge.com.ssl.access.log-20180902.gz
/path/to/hogehoge.com.ssl.access.log-20180826.gz
/path/to/hogehoge.com.ssl.access.log-20180901.gz
/path/to/hogehoge.com.ssl.access.log-20180825.gz
/path/to/hogehoge.com.ssl.access.log-20180830.gz
/path/to/hogehoge.com.ssl.access.log-20180903.gz
/path/to/hogehoge.com.ssl.access.log-20180827.gz

xargs

|以前のコマンドの実行結果を引数にして、xargs以降のコマンドを実行する。
今回は上記のfindコマンドの結果を一行ずつzgrepコマンドの引数として渡している。

余談だが、-pオプションを指定すると、「このコマンドを実行するけどいい?」というプロンプトを、実行予定のコマンド文字列と共に表示してくれる。
どんなコマンドが実行されるか一目瞭然なので、これを上手く利用するとxargsと仲良くなりやすい。

zgrep

.gz拡張子のファイルをそのまま扱えるgrepみたいなものという認識。
lotateされたログファイルは.gzになっているのでgrepではなくzgrepを使用している。
(あとで調べてみたらzgrepgrep -Zと同じらしい)
https://nxmnpg.lemoda.net/ja/1/zgrep

-wは単語として含まれている物を検索、-cはヒットした行を表示するのでなく、その行をカウントするオプション。

sort

日付順に並んでてほしいなと思ったので。

最後に

GUI生まれGUI育ちなのでシェルに苦手意識を持っていたが、「パイプは結果をそのまま渡してあげてるだけ」ということと、「xargsはパイプで渡された結果を(-Lオプションで指定しなければ)1行ずつ引数にしてコマンドを実行しているだけ」ということを意識した結果、実現したいこと実現できるコマンドを自分の力で書けて気持ちよかった。