特定の日付範囲(8月~9月とか)のファイル内をgrepして、さらに範囲ごとの件数カウントまで行う方法を紹介します。
前提&実行コマンド
とあるログの月ごとの出力件数をカウントする必要があった時に、表題の方法で調査をしたので備忘も兼ねて紹介します。
テストで作成したファイル群は以下。
[test@localhost date_grep]$ ls -ltr
合計 48
-rw-rw-r-- 1 test test 6 4月 1 2022 file1
-rw-rw-r-- 1 test test 6 4月 1 2022 file2
-rw-rw-r-- 1 test test 0 4月 1 12:00 file3
-rw-rw-r-- 1 test test 6 4月 1 13:00 file4
-rw-rw-r-- 1 test test 6 4月 1 14:00 file5
-rw-rw-r-- 1 test test 6 5月 1 12:00 file6
-rw-rw-r-- 1 test test 6 5月 1 13:00 file7
-rw-rw-r-- 1 test test 0 5月 1 14:00 file8
-rw-rw-r-- 1 test test 0 5月 1 15:00 file9
-rw-rw-r-- 1 test test 0 6月 1 12:00 file10
-rw-rw-r-- 1 test test 0 6月 1 13:00 file11
-rw-rw-r-- 1 test test 6 7月 1 12:00 file12
-rw-rw-r-- 1 test test 6 7月 1 13:00 file13
-rw-rw-r-- 1 test test 6 8月 1 12:00 file14
-rw-rw-r-- 1 test test 0 8月 1 13:00 file15
-rw-rw-r-- 1 test test 6 8月 1 14:00 file16
-rw-rw-r-- 1 test test 6 8月 1 15:00 file17
-rw-rw-r-- 1 test test 6 9月 1 12:00 file18
[test@localhost date_grep]$
touch コマンドは -t オプションで日付指定したファイルを作れるんですね、初知りでした。
[test@localhost date_grep]$ touch -t 202204011200 file{1..2}
次のファイル内に error という文字列を仕込んだので、これをカウント対象とします。
[test@localhost date_grep]$ grep error *
file1:error
file12:error
file13:error
file14:error
file16:error
file17:error
file18:error
file2:error
file4:error
file5:error
file6:error
file7:error
[test@localhost date_grep]$
指定範囲を2023年6月~9月として、error の件数を月ごとにカウント。
[test@localhost date_grep]$ i=6;while [ $i -le 9 ]; do echo -n "2023-$i: "; ls -ltr --time-style=long-iso | grep "2023-0$i-" | awk '{print $8}'| xargs grep error | wc -l; i=`expr $i + 1`; done
2023-6: 0
2023-7: 2
2023-8: 3
2023-9: 1
[test@localhost date_grep]$
解説
ワンライナーでやっているので細かく分けて解説します。
i=6;while [ $i -le 9 ]; do
範囲を6月~9月にしたので ここで while 文の範囲を指定しています。
echo -n "2023-$i: ";
これはただの結果出力用です。
ls -ltr --time-style=long-iso | grep "2023-0$i-" | awk '{print $8}'
ls コマンドの結果は設定によって若干異なると思いますが、今回はまず ls -l の結果から年部分を grep することを前提にしています。
そのため、--time-style=long-iso をつけて date 列に年が確実に出るようにしました。
[test@localhost date_grep]$ ls -ltr --time-style=long-iso
合計 48
-rw-rw-r-- 1 test test 6 2022-04-01 12:00 file1
-rw-rw-r-- 1 test test 6 2022-04-01 13:00 file2
-rw-rw-r-- 1 test test 0 2023-04-01 12:00 file3
-rw-rw-r-- 1 test test 6 2023-04-01 13:00 file4
-rw-rw-r-- 1 test test 6 2023-04-01 14:00 file5
-rw-rw-r-- 1 test test 6 2023-05-01 12:00 file6
-rw-rw-r-- 1 test test 6 2023-05-01 13:00 file7
-rw-rw-r-- 1 test test 0 2023-05-01 14:00 file8
-rw-rw-r-- 1 test test 0 2023-05-01 15:00 file9
-rw-rw-r-- 1 test test 0 2023-06-01 12:00 file10
-rw-rw-r-- 1 test test 0 2023-06-01 13:00 file11
-rw-rw-r-- 1 test test 6 2023-07-01 12:00 file12
-rw-rw-r-- 1 test test 6 2023-07-01 13:00 file13
-rw-rw-r-- 1 test test 6 2023-08-01 12:00 file14
-rw-rw-r-- 1 test test 0 2023-08-01 13:00 file15
-rw-rw-r-- 1 test test 6 2023-08-01 14:00 file16
-rw-rw-r-- 1 test test 6 2023-08-01 15:00 file17
-rw-rw-r-- 1 test test 6 2023-09-01 12:00 file18
[test@localhost date_grep]$
あとは awk を用いてファイル名だけを後ろに渡します。
xargs grep error | wc -l
前処理にて、ファイル名だけが渡されているので、xargs で各ファイルに対して grep 検索をし、wc -l でカウントします。
grep -c だとファイル名が余分に出力されるので wc -l が良いです。
i=`expr $i + 1`; done
i (カウンタ変数) のカウントを 1up し、次のループへ行きます。
実際は指定する日付範囲やファイル名等々によってさらにコマンドを修正する必要があると思いますが、だいたいこんな感じです。
GCPのロギングなどにログを流していればGUI上でクエリ投げるだけで全部楽にできるんですけど、今回は Linuxでのやり方紹介でした。
気に入ったらぜひ共有してください。