2016-06-18 18 views
1

で大きなファイルを解析するとき、私は同じ行に2つのパターンの最後の出現を取得するためにmail.logファイルを解析したいと思い、解析されるファイルは500メガバイト& 1ギガバイトパフォーマンスの問題は、awkの

の間のサイズを有します

は、私はそれを得るために管理:

$ time awk ' $5~"postfix/error" && $6~"4F0A73A11CF" ' MAIL-POSTFIX-LOG-20160226.log | 
tail -1 

Feb 26 21:49:23 smtp1 postfix/error[32347]: 4F0A73A11CF: to=<[email protected]>, 
relay=none, delay=88661, delays=88661/0.02/0/0.05, dsn=4.4.1, status=deferred (delivery 
temporarily suspended: connect to xxxxxxxxxxxxxxxxxxxx[x.x.x.x]:25: Connection timed out) 

real 0m3.572s 
user 0m1.920s 
sys  0m1.600s 

私はawkコマンドを使用して維持したいと思いますが、私は劇的データの数日間を解析するためのパフォーマンスを改善する必要があります。

は、最後の1で始まる、ファイルを逆にTACコマンドを使用することにより、私は、grepコマンドで改善された性能を観察:

$ time tac MAIL-POSTFIX-LOG-20160226.log | grep "postfix/error" | grep -m1 "4F0A73A11CF" 

Feb 26 21:49:23 smtp1 postfix/error[32347]: 4F0A73A11CF: to=<[email protected]>, 
relay=none, delay=88661, delays=88661/0.02/0/0.05, dsn=4.4.1, status=deferred (delivery 
temporarily suspended: connect to xxxxxxxxxxxxxxxxxxxx[x.x.x.x]:25: Connection timed out) 

real 0m0.026s 
user 0m0.008s 
sys  0m0.016s 

$ time cat MAIL-POSTFIX-LOG-20160226.log | grep "postfix/error" | grep "4F0A73A11CF" | 
tail -1 

Feb 26 21:49:23 smtp1 postfix/error[32347]: 4F0A73A11CF: to=<[email protected]>, 
relay=none, delay=88661, delays=88661/0.02/0/0.05, dsn=4.4.1, status=deferred (delivery 
temporarily suspended: connect to xxxxxxxxxxxxxxxxxxxx[x.x.x.x]:25: Connection timed out) 

real 0m2.979s 
user 0m0.280s 
sys  0m0.680s 

しかし、TACとawkコマンド、パフォーマンスを兼ね備えしようとしたとき予想1ではありません。

time tac MAIL-POSTFIX-LOG-20160226.log | awk ' $5~"postfix/error" && $6~"4F0A73A11CF" ' | 
head -1 

Feb 26 21:49:23 smtp1 postfix/error[32347]: 4F0A73A11CF: to=<[email protected]>, 
relay=none, delay=88661, delays=88661/0.02/0/0.05, dsn=4.4.1, status=deferred (delivery 
temporarily suspended: connect to xxxxxxxxxxxxxxxxxxxx[x.x.x.x]:25: Connection timed out) 

real 0m19.232s 
user 0m2.840s 
sys  0m4.836s 

任意の提案

よろしく

+0

を 'と'フィールド区切り記号として、あなたのawk状態で '〜'の代わりに '='を使うこともできます(フィールド番号も同様に変わることに注意してください)。 – jas

+0

私は "["についてのコメントを理解していますか、私は試しました: time tac MAIL-POSTFIX-LOG-20160226.log | awk -F ':' '$ 3〜 "postfix/error" && $ 4 == "4F0A73A11CF"' |ヘッドは-1 本当0m16.003s ユーザーが SYS 0m3.984s は、私は4番目のフィールド「4F0A73A11CF」、大した改善のためのスペースを追加する必要がありました0m2.756s。 – Fdv

+0

"grep -m1"のような最初のマッチの後にawkコマンドを停止することは可能です そうでなければtacを使用することは役に立たない – Fdv

答えて

0

私はこの問題は最初の試合後に出たときに、性能が増加し、ヘッドへの配管れると思う: `[`あなたには、多分あれば、データのご一行を見てからの仮定を作る

time tac MAIL-POSTFIX-LOG-20160226.log | awk ' $5~"error" && $6~"4F0A73A11CF" {print; exit} ' 

real 0m0.048s 
user 0m0.024s 
sys  0m0.020s 
+0

。パイプラインでのバッファリングの問題を取り除き、最初の試合でawkを確実に停止します。また、regexpデリミタ( '/.../')の代わりに正規表現の前後に文字列デリミタ( '' ... ... '')を使うことで、awkを2回ハードに動作させ、文字列をregexpsに変換する必要がありますregexpを評価するためにもう一度。正規表現を区切るにはregexpデリミタを使います: '$ 5〜/ error/&& $ 6〜/ 4F0A73A11CF /'。また、2つの正規表現比較ではなく、awkと/ postfixとの間の比較で小さな改善が見られるかもしれません:4F0A73A11CF/{print; exit} ''を実行します。 –

+0

Thx私はawkで複数の区切り文字を使用する可能性を認識しておらず、文字列区切り文字を正規表現で使用した場合の影響も認識していませんでした。 – Fdv