発生回数に応じて印刷を制限する方法(AWK)

発生回数に応じて印刷を制限する方法(AWK)

だから私はhttpsを介して私たちのネットワークでポルノを探している人を追跡しようとしています。 15回以上の連続画像クリックでBroログのHTTPヘッダーに参照URLがない場合は、パターンを簡単に確認できます。

Broの関連列は、$ 3 =ホストIP、$ 11 =リファラー、$ 14 =ファイルサイズ、$ 27 = MIMEタイプです。

だから私が現在使用しています...

awk -F "\t" '$11 ~ /^\-$/ && $14 > 100000 && $27 ~ /^image/'

私がやりたいことは、1行のコマンドでサブコマンドを実行し続け、awkに$ 3のIPが15回以上表示される行だけを印刷するように指示する方法があるかどうかを知ることです。

私の考えでは、似たようなことをするにはawkプログラムを作らなければならないようです。この問題を回避するのに役立つ専門家がここにいることを願っています。私は他の正規表現コマンドがよりうまく機能する場合(perl、grep、egrep、agrep、bro-cut)を使用することに反対しません。

更新:これを説明する最善の方法は、Excel用語を使用することです。 awkにはcountif Excel関数に似た機能がありますか? =個数(C1,C:C)>15

サンプルログ:

1443534069  CGAdXyZgN3wVwihi6   123.456.789.012 59713   93.184.216.98   80  1   GET 40.media.tumblr.com /1fbe50fff7a17f84acdc30b03d9b6335/tumblr_nvf1dfH8oz1tco00do1_500.jpg    -   Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.99 Safari/537.36    0   89522   200 OK  -   -   -   (empty) -   -   -   -   -   FIGAv51OT15ak4eDCl  image/jpeg
1443534069  CkST1DjXDkCBDYhYa   123.456.789.012 59712   93.184.216.98   80  1   GET 40.media.tumblr.com /e8f958e0dcd3eb419035a8d3271d07e8/tumblr_npr5drTCOO1qk489oo1_500.jpg    -   Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.99 Safari/537.36    0   83743   200 OK  -   -   -   (empty) -   -   -   -   -   FWRWZX2XgQQqfm9OMe  image/jpeg
1443534069  C8GvXwqAiR84PGGkk   123.456.789.012 59714   93.184.216.98   80  1   GET 40.media.tumblr.com /0b80deef543f6da28b48db0578fb3bd4/tumblr_n0chjkQICf1qeu577o1_500.jpg    -   Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.99 Safari/537.36    0   70530   200 OK  -   -   -   (empty) -   -   -   -   -   FOHdJ62uCU30UE9VYg  image/jpeg
1443534069  CMXgz73HlqL5Z0WVR7  123.456.789.012 59715   54.230.193.223  80  1   GET 36.media.tumblr.com /547822945f762adb310bb966c1f9c886/tumblr_nv3xgebHVH1sbsr1vo1_500.jpg    -   Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.99 Safari/537.36    0   67589   200 OK  -   -   -   (empty) -   -   -   -   -   FmaN4d2eimhA2CpEmd  image/jpeg

答え1

このPerlスクリプトは、基準( "image /"、> 100000バイト、参照者= '-')と一致する各ログ行をIPアドレスとして入力された配列ハッシュに保存します。スクリプトの最後に、14個以上のエントリを含むすべてのIPアドレスのすべての配列行を印刷します。

多くのメモリを使用しますが、各入力行を格納するほど多くはありません。

1行に圧縮できますが、何らかの理由で読み取れない、またはデバッグできません。

#! /usr/bin/perl

use strict;

my %LOGLINES = ();

while (<>) {
    next unless (/\bimage\//);
    my @F=split("\t");
    next unless ($F[10] eq '-');
    next unless ($F[13] > 100000);

    push @{ $LOGLINES{$F[2]} }, $_;
};  

foreach my $key (sort keys %LOGLINES) {
   print @{ $LOGLINES{$key} } if (scalar @{ $LOGLINES{$key} } > 14);
}  

Perl配列は1ベースではなく0ベースです。したがって、フィールド番号は、指定したフィールド番号から-1だけオフセットされます。

ここに表示されている各IPアドレスに対して最大15行だけ保存してから、表示される一致する行の印刷を開始するため、多くのメモリを使用しない別のバージョンがあります。欠点は、出力がIPアドレスによってソートされないことですsort -t $'\t' -k2

#! /usr/bin/perl

use strict;

my %LOGLINES = ();
my %count = ();

while (<>) {
    next unless (/\bimage\//);
    my @F=split("\t");
    next unless ($F[10] eq '-');
    next unless ($F[13] > 12000);

    $count{ $F[2] }++;

    if ($count{ $F[2] } == 15) {
      print @{ $LOGLINES{$F[2]} };   # print all the log lines we've seen so far
      print $_;                      # print the current line
    } elsif ($count{ $F[2] } > 15) {
      print $_;                      # print the current line
    } else {
      push @{ $LOGLINES{$F[2]} }, $_; # store the log line for later use
    }
};

関連情報