PerlまたはPythonでログ解析スクリプトを再構築します(awkを削除)。

PerlまたはPythonでログ解析スクリプトを再構築します(awkを削除)。

ログファイルでボットアクティビティをフィルタリングする作業を完了する必要があります。

ソリューションは、次の基準を満たすレコードのみを表示する必要があります。

  • ユーザーはログインし、パスワードを変更し、同じ瞬間にログアウトします。
  • これらのアクション(ログイン、パスワードの変更、ログアウト)は、間に他のエントリなしで順番に発生します。

入力データの例

[a lot of data]
Mon, 22 Aug 2016 13:15:39 +0200|178.57.66.225|fxsciaqulmlk| - |user logged in| -
Mon, 22 Aug 2016 13:15:39 +0200|178.57.66.225|fxsciaqulmlk| - |user changed password| -
Mon, 22 Aug 2016 13:15:39 +0200|178.57.66.225|fxsciaqulmlk| - |user logged off| -
Mon, 22 Aug 2016 13:15:42 +0200|178.57.66.225|faaaaaa11111| - |user logged in| -
Mon, 22 Aug 2016 13:15:40 +0200|178.57.66.215|terdsfsdfsdf| - |user logged in| -
Mon, 22 Aug 2016 13:15:49 +0200|178.57.66.215|terdsfsdfsdf| - |user changed password| -
Mon, 22 Aug 2016 13:15:49 +0200|178.57.66.215|terdsfsdfsdf| - |user logged off| -
Mon, 22 Aug 2016 13:15:59 +0200|178.57.66.205|erdsfsdfsdf| - |user logged in| -
Mon, 22 Aug 2016 13:15:59 +0200|178.57.66.205|erdsfsdfsdf| - |user changed password| -
Mon, 22 Aug 2016 13:15:59 +0200|178.57.66.205|erdsfsdfsdf| - |user logged off| -
Mon, 22 Aug 2016 13:17:50 +0200|178.57.66.205|abcbbabab| - |user logged in| -
Mon, 22 Aug 2016 13:17:50 +0200|178.57.66.205|abcbbabab| - |user changed password| -
Mon, 22 Aug 2016 13:17:50 +0200|178.57.66.205|abcbbabab| - |user changed profile| -
Mon, 22 Aug 2016 13:17:50 +0200|178.57.66.205|abcbbabab| - |user logged off| -
Mon, 22 Aug 2016 13:19:19 +0200|178.56.66.225|fxsciaqulmla| - |user logged in| -
Mon, 22 Aug 2016 13:19:19 +0200|178.56.66.225|fxsciaqulmla| - |user changed password| -
Mon, 22 Aug 2016 13:19:19 +0200|178.56.66.225|fxsciaqulmla| - |user logged off| -
Mon, 22 Aug 2016 13:20:42 +0200|178.57.67.225|faaaa0a11111| - |user logged in| -
[a lot of data]

タスクを実行するために、次のコードを書きました。

awk 'BEGIN { FS=" " } { c[$5]++; l[$5,c[$5]]=$0 } END { for (i in c) { if (c[i] == 3) for (j = 1 ; j <= c[i]; j++) print l[i,j] } }' $1

使用法:

./parse_log.sh ログファイル.log

出力:

Mon, 22 Aug 2016 13:15:39 +0200|178.57.66.225|fxsciaqulmlk| - |user logged in| -
Mon, 22 Aug 2016 13:15:39 +0200|178.57.66.225|fxsciaqulmlk| - |user changed password| -
Mon, 22 Aug 2016 13:15:39 +0200|178.57.66.225|fxsciaqulmlk| - |user logged off| -
Mon, 22 Aug 2016 13:15:59 +0200|178.57.66.205|erdsfsdfsdf| - |user logged in| -
Mon, 22 Aug 2016 13:15:59 +0200|178.57.66.205|erdsfsdfsdf| - |user changed password| -
Mon, 22 Aug 2016 13:15:59 +0200|178.57.66.205|erdsfsdfsdf| - |user logged off| -
Mon, 22 Aug 2016 13:19:19 +0200|178.56.66.225|fxsciaqulmla| - |user logged in| -
Mon, 22 Aug 2016 13:19:19 +0200|178.56.66.225|fxsciaqulmla| - |user changed password| -
Mon, 22 Aug 2016 13:19:19 +0200|178.56.66.225|fxsciaqulmla| - |user logged off| -

しかし、PerlやPythonで書かれた代替手段(外部ライブラリを最小限に使用)がどのように見えるのか疑問に思います。

ベストアンサー1

これは答えではありませんが、コメントとして書くには大きすぎてフォーマットする必要があるため、「Pythonコードが実行する操作を読みやすく理解するのは簡単です」というコメントを処理するには、合理的な変数名を使用するAWKスクリプトです。考える あなたのPythonスクリプトPythonスクリプトとよく似ているようですが、awkはテキストを操作するためにPythonでコーディングする必要があるすべての一般的な操作をすでに実行しているため、短くなります。

awk -v column=5 '
    { records[$column] = records[$column] $0 ORS }
    END {
        for ( timestamp in records ) {
            if ( gsub(ORS,"&",records[timestamp]) > 2 ) {
                printf "%s", records[timestamp]
            }
        }
    }
' logfile.log

ただし、処理する前にファイル全体をメモリに読み込むことは、この問題を解決する非常に非効率的な方法です。時間が変わるたびにテストして印刷する必要があります。

awk -v column=5 '
    $column != prev {
        prt()
        records = ""
        prev = $column
    }
    { records = records $0 ORS }
    END { prt() }

    function prt() {
        if ( gsub(ORS,"&",records) > 2 ) {
            printf "%s", records
        }
    }
' logfile.log

おすすめ記事