0

大きなログ ファイル行からいくつかの情報を解析する必要があります。そのようなもの

abc.log:2012-03-03 11:12:12,457 ABC[123.RPH.-101] XYZ: Query=get_data @a=0,@b=1 Rows=10Time=100   

ログファイルには、上記のようなログ行が多数あります。datetime ie 2012-03-03 11:12:12,457 job details ie 123.RPH.-101 Query ie get_data (no parameters) Rows ie 10 Time ie 100 のような情報を抽出する必要があります

したがって、出力は次のようになります

2012-03-03 11:12:12,457|123|-101|get_data|10|100  

awk でさまざまな順列計算を試みましたが、うまくいきませんでした。

4

5 に答える 5

1

TXR:

@(collect :vars ())
@file:@year-@mon-@day @hh:@mm:@ss,@ms @jobname[@job1.RPH.@job2] @queryname: Query=@query @params Rows=@{rows /[0-9]+/}Time=@time
@(output)
@year-@mon-@day @hh-@mm-@ss,@ms|@job1|@job2|@query|@rows|@time
@(end)
@(end)

走る:

$ txr data.txr data.log
2012-03-03 11-12-12,457|123|-101|get_data|10|100

これは、ログファイルのすべての行がパターンに一致する必要があることをプログラムにアサートさせる1つの方法です。まず、コレクションにギャップを入れないでください。これは、一致しない資料をスキップして、一致する行を探すことはできないことを意味します。

@(collect :gap 0 :vars ())

次に、スクリプトの最後にこれを追加します。

@(eof)

これは、ファイルの終わりでの一致を指定します。(制約@(collect)のために)行が一致しないために早期にベイルした場合、は失敗するため、スクリプトは失敗したステータスで終了します。:gap 0@(eof)

このタイプのタスクでは、フィールド分割正規表現ハックは、処理中の入力の一部のサブセットに対して盲目的に誤った結果を生成する可能性があるため、逆効果になります。入力に膨大な数の行が含まれている場合、間違いをチェックする簡単な方法はありません。パターンの基になっている例に似ていないものを拒否する可能性が高い、非常に具体的な一致を設定することをお勧めします。

于 2012-04-06T19:34:26.493 に答える
1

もう1つの、それほど派手ではないAWKソリューションがあります(ただし、mawkでも機能します)。

BEGIN { OFS="|" }

{
    i = match($3, /\[[^]]+\]/)
    job = substr($3, i + 1, RLENGTH - 2)
    split($5, X, "=")
    query = X[2]
    split($7, X, "=")
    rows = X[2]
    split($8, X, "=")
    time= X[2]

    print $1 " " $2, job, query, rows, time
}

これは、文字列がスペースで区切られていることを前提としていRows=10ますTime=100。つまり、質問の例にタイプミスがありました。

于 2012-04-06T19:44:34.140 に答える
1

gawk での私の解決策: gawk 拡張機能を使用して一致させます。

ファイル形式の仕様を指定しなかったため、正規表現を調整する必要がある場合があります。

スクリプトの呼び出し: gawk -v OFS='|' -f script.awk

{
match($0, /[0-9]+-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+,[0-9]+/)
date_time = substr($0, RSTART, RLENGTH)

match($0, /\[([0-9]+).RPH.(-?[0-9]+)\]/, matches)
job_detail_1 = matches[1]
job_detail_2 = matches[2]

match($0, /Query=(\w+)/, matches)
query = matches[1]

match($0, /Rows=([0-9]+)/, matches)
rows = matches[1]

match($0, /Time=([0-9]+)/, matches)
time = matches[1]

print date_time, job_detail_1, job_detail_2, query,rows, time
}
于 2012-04-06T19:42:16.553 に答える
1

うーん、これは本当に恐ろしいことですがsed、タグに記載されているため、まだ回答がありません...

sed -e 's/[^0-9]*//' -re 's/[^ ]*\[([^.]*)\.[^.]*\.([^]]*)\]/| \1 | \2/' -e 's/[^ ]* Query=/| /' -e 's/ [^ ]* Rows=/ | /' -e 's/Time=/ | /' my_logfile
于 2012-04-06T19:28:45.317 に答える
0

正しいフィールドセパレータが必要です

awk -F '[][ =.]' -v OFS='|' '{print $1 " " $2, $4, $6, $10, $15, $17}'

「abc.log:」が実際にはログ ファイルにないと仮定しています。

于 2012-04-06T20:48:13.327 に答える