シェル入門:uidごとにgrepして、別ファイルに出力する

スポンサーリンク
シェル入門:uidごとにgrepして、別ファイルに出力する ノウハウ
シェル入門:uidごとにgrepして、別ファイルに出力する
この記事は約6分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

今日は、bashを利用したテキストの抽出方法についてご紹介します。

スポンサーリンク

背景

MonologのUidProcessorを利用して、ログにリクエストを識別するuidを付与しています。例えば、下記のような出力になっています。

2023-09-06T14:16:50.611759+00:00	fd2b5fb	DEBUG	GET	localhost/	10	Closure->{closure}(22)	Hello world!	[]	{"memory_usage":"4 MB","memory_peak_usage":"4 MB","file":"/var/www/slim_app/app/routes.php","ip":"172.19.0.1","referrer":null}
2023-09-06T14:16:51.358210+00:00	a3c6d79	DEBUG	GET	localhost/	7	Closure->{closure}(22)	Hello world!	[]	{"memory_usage":"4 MB","memory_peak_usage":"4 MB","file":"/var/www/slim_app/app/routes.php","ip":"172.19.0.1","referrer":null}
2023-09-06T14:16:51.672733+00:00	9da566b	DEBUG	GET	localhost/	9	Closure->{closure}(22)	Hello world!	[]	{"memory_usage":"4 MB","memory_peak_usage":"4 MB","file":"/var/www/slim_app/app/routes.php","ip":"172.19.0.1","referrer":null}
2023-09-06T14:16:53.976604+00:00	7af6925	DEBUG	GET	localhost/	8	Closure->{closure}(22)	Hello world!	[]	{"memory_usage":"4 MB","memory_peak_usage":"4 MB","file":"/var/www/slim_app/app/routes.php","ip":"172.19.0.1","referrer":null}
2023-09-06T14:16:54.173788+00:00	ba7fda4	DEBUG	GET	localhost/	11	Closure->{closure}(22)	Hello world!	[]	{"memory_usage":"4 MB","memory_peak_usage":"4 MB","file":"/var/www/slim_app/app/routes.php","ip":"172.19.0.1","referrer":null}
2023-09-06T14:16:54.930687+00:00	18cf919	DEBUG	GET	localhost/	10	Closure->{closure}(22)	Hello world!	[]	{"memory_usage":"4 MB","memory_peak_usage":"4 MB","file":"/var/www/slim_app/app/routes.php","ip":"172.19.0.1","referrer":null}
2023-09-06T14:16:55.250928+00:00	9f082c1	DEBUG	GET	localhost/	7	Closure->{closure}(22)	Hello world!	[]	{"memory_usage":"4 MB","memory_peak_usage":"4 MB","file":"/var/www/slim_app/app/routes.php","ip":"172.19.0.1","referrer":null}

このとき、uidごとにログを抽出して分析したい場面があり、そのときに使用したシェルを備忘として残しました。

使用したスクリプト

ログが app.log というファイルの場合、下記のスクリプトを使用しました。

cat app.log \
  | awk '{print $2}' \
  | sort \
  | uniq \
  | xargs -t -P $(nproc) -I {} -n 1  sh -c "grep {} app.log > logs/{}.log"

実行結果

下記のファイルが出力されていれば成功です。

logs
├── 18cf919.log
├── 7af6925.log
├── 9da566b.log
├── 9f082c1.log
├── a3c6d79.log
├── ba7fda4.log
└── fd2b5fb.log

解説

このコードは、ログファイル (app.log) から一意な値(重複を取り除いた値)を抽出し、それぞれの値に対して個別のログファイルを生成するシェルスクリプトの一部です。以下はコードのステップごとの説明です。

  1. cat app.log:
    このコマンドは、app.log ファイルの内容を標準出力に出力します。つまり、ファイルの内容を表示します。
  2. awk '{print $2}':
    awk コマンドは、テキスト処理用の強力なツールで、指定されたパターンにマッチする行を処理できます。この場合、$2 は各行の2番目のフィールド(スペースで区切られた単語またはデータ)を抽出します。したがって、このステップでは app.log ファイルの各行から2番目のフィールドを抽出して、それを標準出力に出力します。
  3. sort:
    sort コマンドは、行をアルファベット順にソートします。この場合、一意な値(2番目のフィールド)がソートされます。
  4. uniq:
    uniq コマンドは、連続する重複行を取り除いて一意な行のみを残します。このコードでは、一意な値だけが出力されます。
  5. xargs -t -P $(nproc) -I {} -n 1 sh -c "grep {} app.log > logs/{}.log":
    この部分は、一意な値を処理し、それぞれの値に対してログファイルを生成する部分です。以下は各オプションとコマンドの説明です:
  • -t: 実行するコマンドを表示します。
  • -P $(nproc): 同時に実行するプロセスの数を、システムのCPUコア数 (nproc コマンドで取得) に設定します。
  • -I {}: {} というプレースホルダを指定します。このプレースホルダは後で一意な値に置き換えられます。
  • -n 1: 各コマンドを1回だけ実行します。
  • sh -c "grep {} app.log > logs/{}.log": このコマンドは、grep コマンドを使用して、一意な値(プレースホルダ {} に置き換えられる)を app.log ファイルから検索し、それを個別のログファイル (logs/{}.log) に保存します。

したがって、このコードは app.log ファイルから一意な値を取得し、それぞれの値に対して個別のログファイルを生成します。各ログファイルには、元のログファイルから一意な値に一致する行が含まれます。このプロセスは、複数のプロセスを使用して高速化され、システムのCPUコア数に応じて並列処理が行われます。

おわりに

今日は、bashを利用したテキストの抽出方法についてご紹介しました。

よっしー
よっしー

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました