awkでgrepのように行を抽出する
Pocket

大体の事はなんでも出来るawkだが、grepのように行を抽出する事も出来る。
以下のようにコマンドを実行することで、文字列を含む行の抽出を行える。

awk '/文字列/' 対象ファイル
[root@test-node ~]# cat /tmp/sample.log
2016/04/25 00:00:01 : [11.25] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [123]
2016/04/25 00:00:01 : [9.76] SELECT BBB.* FROM BBB WHERE BBB.yyy = ? AND BBB.zzz; [19,234]
2016/04/25 00:00:01 : [17.32] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [13]
2016/04/25 00:00:02 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [22,52]
2016/04/25 00:00:02 : [15.05] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [2345]
2016/04/25 00:00:03 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [39,1952]
2016/04/25 00:00:04 : [8.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [423,1222]
2016/04/25 00:00:05 : [14.45] SELECT BBB.* FROM BBB WHERE BBB.yyy = ? AND BBB.zzz; [9,33234]
[root@test-node ~]# awk '/AND/' /tmp/sample.log
2016/04/25 00:00:01 : [9.76] SELECT BBB.* FROM BBB WHERE BBB.yyy = ? AND BBB.zzz; [19,234]
2016/04/25 00:00:02 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [22,52]
2016/04/25 00:00:03 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [39,1952]
2016/04/25 00:00:04 : [8.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [423,1222]
2016/04/25 00:00:05 : [14.45] SELECT BBB.* FROM BBB WHERE BBB.yyy = ? AND BBB.zzz; [9,33234]

 

awkの場合、指定した文字列を含む場合もそうだが、「NR」で行数を指定しての抽出も可能だ。

awk 'NR==行' 対象ファイル
[root@test-node ~]# cat -n /tmp/sample.log
     1  2016/04/25 00:00:01 : [11.25] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [123]
     2  2016/04/25 00:00:01 : [9.76] SELECT BBB.* FROM BBB WHERE BBB.yyy = ? AND BBB.zzz; [19,234]
     3  2016/04/25 00:00:01 : [17.32] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [13]
     4  2016/04/25 00:00:02 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [22,52]
     5  2016/04/25 00:00:02 : [15.05] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [2345]
     6  2016/04/25 00:00:03 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [39,1952]
     7  2016/04/25 00:00:04 : [8.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [423,1222]
     8  2016/04/25 00:00:05 : [14.45] SELECT BBB.* FROM BBB WHERE BBB.yyy = ? AND BBB.zzz; [9,33234]
[root@test-node ~]# awk 'NR==3' /tmp/sample.log
2016/04/25 00:00:01 : [17.32] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [13]

 

なお、カンマ区切りにすることで、指定した文字列や行の範囲を抽出することが可能だ。

awk 'NR==最初の行,NR==終わりの行' 対象ファイル
[root@test-node ~]# cat -n /tmp/sample.log
     1  2016/04/25 00:00:01 : [11.25] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [123]
     2  2016/04/25 00:00:01 : [9.76] SELECT BBB.* FROM BBB WHERE BBB.yyy = ? AND BBB.zzz; [19,234]
     3  2016/04/25 00:00:01 : [17.32] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [13]
     4  2016/04/25 00:00:02 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [22,52]
     5  2016/04/25 00:00:02 : [15.05] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [2345]
     6  2016/04/25 00:00:03 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [39,1952]
     7  2016/04/25 00:00:04 : [8.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [423,1222]
     8  2016/04/25 00:00:05 : [14.45] SELECT BBB.* FROM BBB WHERE BBB.yyy = ? AND BBB.zzz; [9,33234]
[root@test-node ~]# awk 'NR==3,NR==6' /tmp/sample.log
2016/04/25 00:00:01 : [17.32] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [13]
2016/04/25 00:00:02 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [22,52]
2016/04/25 00:00:02 : [15.05] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [2345]
2016/04/25 00:00:03 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [39,1952]

Sponsored Links

もちろん、文字列で範囲を指定する事も可能だ。

※ただし、終わりの文字列が複数ある場合、最初の一行目しか抽出しないので注意。

[root@test-node ~]# awk '/2016\/04\/25 00:00:02/,/2016\/04\/25 00:00:04/' /tmp/sample.log
2016/04/25 00:00:02 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [22,52]
2016/04/25 00:00:02 : [15.05] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [2345]
2016/04/25 00:00:03 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [39,1952]
2016/04/25 00:00:04 : [8.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [423,1222]

 

文章内の文字列で指定する場合、対象となる列を指定することも出来る(対象の列がソートされている事が前提だけど)。
サンプルとして使用しているファイルで、「00:00:02」~「00:00:04」までを抽出する場合なら、以下のように記述すればよい。

[root@test-node ~]# cat -n /tmp/sample.log
     1  2016/04/25 00:00:01 : [11.25] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [123]
     2  2016/04/25 00:00:01 : [9.76] SELECT BBB.* FROM BBB WHERE BBB.yyy = ? AND BBB.zzz; [19,234]
     3  2016/04/25 00:00:01 : [17.32] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [13]
     4  2016/04/25 00:00:02 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [22,52]
     5  2016/04/25 00:00:02 : [15.05] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [2345]
     6  2016/04/25 00:00:03 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [39,1952]
     7  2016/04/25 00:00:04 : [8.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [423,1222]
     8  2016/04/25 00:00:05 : [14.45] SELECT BBB.* FROM BBB WHERE BBB.yyy = ? AND BBB.zzz; [9,33234]
[root@test-node ~]# awk '$2 >= "00:00:02" && "00:00:04" >= $2' /tmp/sample.log
2016/04/25 00:00:02 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [22,52]
2016/04/25 00:00:02 : [15.05] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [2345]
2016/04/25 00:00:03 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [39,1952]
2016/04/25 00:00:04 : [8.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [423,1222]

 

複数条件(1行目、文字列XXを含む行を抽出とか)で抽出する場合は、awk内でifを使用してやれば良い。

awk '{if(条件1||条件2) print}' 対象ファイル # or条件
awk '{if(条件1&&条件2) print}' 対象ファイル # and条件
[root@test-node ~]# cat /tmp/sample.txt
日付 時刻 : ログ内容
2016/04/25 00:00:01 : [11.25] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [123]
2016/04/25 00:00:01 : [9.76] SELECT BBB.* FROM BBB WHERE BBB.yyy = ? AND BBB.zzz; [19,234]
2016/04/25 00:00:01 : [17.32] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [13]
2016/04/25 00:00:02 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [22,52]
2016/04/25 00:00:02 : [15.05] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [2345]
2016/04/25 00:00:03 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [39,1952]
2016/04/25 00:00:04 : [8.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [423,1222]
2016/04/25 00:00:05 : [14.45] SELECT BBB.* FROM BBB WHERE BBB.yyy = ? AND BBB.zzz; [9,33234]
[root@test-node ~]# awk '{if( NR==1 || $2 >= "00:00:02") print}' /tmp/sample.txt
日付 時刻 : ログ内容
2016/04/25 00:00:02 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [22,52]
2016/04/25 00:00:02 : [15.05] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [2345]
2016/04/25 00:00:03 : [13.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [39,1952]
2016/04/25 00:00:04 : [8.45] SELECT AAA.ZSC FROM AAA WHERE AAA.xxx = ? AND AAA.qqq; [423,1222]
2016/04/25 00:00:05 : [14.45] SELECT BBB.* FROM BBB WHERE BBB.yyy = ? AND BBB.zzz; [9,33234]
[root@test-node ~]# awk '{if( /2345/ && $2 >= "00:00:02") print}' /tmp/sample.txt
2016/04/25 00:00:02 : [15.05] SELECT AAA.* FROM AAA WHERE AAA.xxx = ? ; [2345]

 

grepでは出来ないような指定もawkでは可能なので、状況に合わせて使い分けてみよう。

 

Pocket

Written by blacknon

インフラ系のSE。一時期はプログラマ。 仮想化とオープンソースに興味あり。一日中寝てたい今日このごろ。 スペインとかで働きたいなぁ…(シエスタがあるので)

Leave a Comment

メールアドレスが公開されることはありません。