テキストファイルから統計を印刷する

テキストファイルから統計を印刷する

以下のテキストファイル(events.dat)があります(抜粋部分のみが表示されます)。

RepID12 01/01/2010 20:56:00 S10
RepID12 01/01/2010 20:56:00 S03
RepID20 01/01/2010 20:56:00 S17
RepID33 01/01/2010 20:56:00 S02
RepID33 01/01/2010 20:56:00 S18
RepID38 01/01/2010 20:56:00 S11
RepID39 01/01/2010 20:56:00 S20
RepID26 02/01/2010 01:39:00 S20
RepID29 02/01/2010 01:39:00 S16
RepID29 02/01/2010 01:39:00 S03
RepID22 02/01/2010 01:39:09 S01
RepID26 02/01/2010 01:39:09 S02
RepID40 02/01/2010 01:39:18 S02
RepID38 02/01/2010 01:39:09 S05
RepID31 02/01/2010 01:39:09 S06
RepID31 02/01/2010 01:39:09 S08
RepID09 02/01/2010 01:39:09 S09
RepID23 02/01/2010 01:39:18 S09
RepID19 02/01/2010 01:40:09 S09
RepID21 02/01/2010 01:40:18 S09
RepID28 02/01/2010 01:40:27 S09
RepID43 02/01/2010 01:40:09 S14

など、合計48時間の時間がかかります。毎分60を超えるイベントが見つかった場合にのみ行を印刷したいと思います。

たとえば、次のコマンドを使用すると、1分間に発生したイベントの数を計算できます。

grep "02/01/2010 01:39" events.dat | wc -l

たとえば、60 が返されます。これは、1 分あたりの最大イベント数です。

同じ操作を実行しながら、合計48時間毎分確認し、1分あたり60以上のイベントが見つかった行のみを印刷するにはどうすればよいですか?事前にありがとう

ベストアンサー1

理想的には、ファイルを一度だけ処理し、メモリにできるだけ少なく保存することをお勧めします。では、awk次のことができます。

awk -v n=60 '
  {
    t = $2 substr($3, 1, 5);
    if (t == last_t) {
      if (++lines > n)
        print
      else
        if (lines == n)
          print saved $0
        else
          saved = saved $0 RS
    } else {
      saved = $0 RS
      lines = 1
      last_t = t
    }
  }' < your-file

このアプローチのいくつかの利点は次のとおりです。

  • これはストリーム処理指向です。入力は到着するとすぐに処理され、出力はできるだけ早く放出されます(ライン60が表示されている場合)。これにより、リアルタイム出力を後処理できます(と同様tail -fn +1 log_file)。
  • コマンド()を一度だけ実行するので、awkできるだけ効率的です。反対の極端はループ内で複数のコマンドを実行する。シェルスクリプトで最も高価な作業は、通常、コマンドを分岐して実行することです。最適化とは、このような状況をできるだけ最小化することを意味します。
  • 最大60行だけがメモリに格納されるため、メモリ使用量が制限されます(行自体のサイズが制限されていると仮定)。
  • awkコードは非常に明確で説明が必要です。サイズが重要な場合は、サイズを小さくして次のように1行に入れることもできます。

    awk '{t=$2substr($3,1,5);if(t==l){if(++i>n)print;else if(i==n)print s$0;else s=s$0RS}else{s=$0RS;i=1;l=t}}' n=60 file
    

おすすめ記事