📝

Awkでログを加工処理する場合のメモ

2024/04/13に公開

ウェブサーバのログなどは、独自にログのフォーマットを調整している場合は別ですが、空白で区切られている場合が多いですね。その中に、ダブルクオーテーションや[]で括られている日付フィールドなどが出てきます。
空白ではなくタブ区切りであれば、awkでフィールドごとに処理するのが簡単になりますが、そうではない場合でも、GNU awkの場合だとFPATを用いることで対応が簡単になります。
sedなどでログをタブ区切りに変換するのも一つの手ではありますが、空白区切りやカンマ区切りのデータをawkでそのまま扱いたい場合、下記のようなFPAT指定で対応できます。

ダブルクォーテーションで区切られている箇所を1つのフィールドとして扱いたい

FPATについて

Field Patternの略でしょうか?
FPATを用いる場合は、FS、FIELDWIDTHSは同時には扱えません。[1][2]

空白区切り

awk -v FPAT='[^ ]*|\"[^\"]*\"'
awk -v FPAT='[^[:space:]]*|\"[^\"]*\"'

カンマ区切り

awk -v FPAT='[^,]*|\"[^\"]*\"'

タブ区切り

awk -v FPAT='[^\t]*|\"[^\"]*\"'

日付が[]で括られている場合

httpdのログで、見かける形式。

  • アクセス日付が[]で括られる。
  • リクエスト部分やユーザーエージェントが""で括られている。

空白区切り

awk -v FPAT='[^ ]*|\"[^\"]*\"|\\[([^\\[\\]])*\\]'

カンマ区切り

awk -v FPAT='[^,]*|\"[^\"]*\"|\\[([^\\[\\]])*\\]'

タブ区切り

awk -v FPAT='[^\t]*|\"[^\"]*\"|\\[([^\\[\\]])*\\]'
awk -v FS="\t"

awkでタブ区切りに変換する場合

空白区切り

awk -v FPAT='[^ ]*|\"[^\"]*\"|\\[([^\\[\\]])*\\]' 'BEGIN{OFS="\t"}{$1=$1;print}'

カンマ区切り

awk -v FPAT='[^,]*|\"[^\"]*\"|\\[([^\\[\\]])*\\]' 'BEGIN{OFS="\t"}{$1=$1;print}'

$1=$1は、OFSを$0に反映させるための、おまじないです。[3]

補足

正規表現でアスタリスクを(*)指定しているのは、0文字のフィールドへの対応です。
タブ区切りへの変換ではなく、カンマ区切りから空白区切りに変換する場合には、0文字のフィールドをダブルクオーテーションで括るなどの配慮が必要でしょう。
またタブ区切りのデータをawkで扱う場合、FS='\t'を指定しましょう。
0文字のフィールドがある場合に、タブが連続で出現します。FSを指定しない場合、連続したタブは連続した空白と同じく一つの区切りとみなされ、フィールドがずれるので注意が必要です。

参考サイト

https://zenn.dev/forcia_tech/articles/20230111_yoshinari
https://qiita.com/ichiro-kazusa/items/7cd010908b53d6dd971b

脚注
  1. https://www.gnu.org/software/gawk/manual/gawk.html#Working-With-Comma-Separated-Value-Files ↩︎

  2. https://www.gnu.org/software/gawk/manual/gawk.html#FS-versus-FPAT ↩︎

  3. https://qiita.com/ichiro-kazusa/items/7cd010908b53d6dd971b ↩︎

Discussion