awkを使用して最後のnゲームの平均を計算します。

awkを使用して最後のnゲームの平均を計算します。

私のファイルがますます大きくなっています。その間、私のサポートプロセスのログを書きます。そのファイルには、次のように「Speed」ログがあります。

(some text)
speed= 1x
(some text)
speed= 1x
(some text)
speed= 1x
(some text)
speed= 0.9x
..
..
(some text)
speed= 0.8x
(some text)

平均速度を得るために以下のコードを試しました。

 awk '/speed/ {gsub("x","");print $2}' $PROCESS_LOG_FILE | awk -F : '{sum+=$1} END {print sum/NR}'

最近120項目の平均を取得できますか? grepとtailを使ってみましたが、ファイルが増え続けて時間がかかります。

答え1

多少無理があるかもしれませんが、tac一時lseekファイルを介して必要な時点を定義し、120の速度に達するまでそこで逆さまに作業します。

tac file | awk '/speed/ {SUM += $2; if (++C == 120) {print SUM/C; exit}}'

または、パターンが120回未満で発生する可能性がある入力を処理します。

tac file | awk '/speed/ {SUM += $2; if (++C == 120) exit}
                END {if (C) print SUM/C}'

答え2

これを行うには、awkの代わりにperlを使用します。過去120の速度を非常に簡単に覚えてください。

perl -MList::Util=sum -nE '
    if (/speed= ([\d.]+)/) {@speeds = ($1, @speeds)[0..119]} 
    # could also write:
    #   if (/speed= ([\d.]+)/) {push @speeds, $1; shift @speeds if @speeds > 120}

    END {say @speeds == 0 ? "No matches" : sum(@speeds)/@speeds}
' speed.log

答え3

円形テーブルを使用する必要があります。以下は、最後の5つの値を含むサンプルコードです。

BEGIN { maxi=5 ; c=0 ; nb=0 ;  }
/^speed/ { list[nb++]=$2 ; nb=nb % maxi ;
   c++ ; if (c> maxi) c=maxi ;
   s=0 ;
   for(i=0;i<=c;i++) s+=list[i] ;
   printf "NR: %d, c=%d, s=%d AVG : %3.2f\n",NR,c,s,s/c ;
}

これをサンプルファイル(またはコマンドラインに値を入力してコマンドライン)でテストできます。

awk -f avg.awk sample.txt

次に、5を120に置き換えてprintf適切に配置します。

末尾は+=$2無視されますx

答え4

これはあなたに効果がありますか?

grep speed test | tail -n 120 | cut -d " " -f 2 | cut -d "x" -f 1 | awk -F : '{sum+=$1} END {print sum/NR}'

私はちょうどあなたの入力をというファイルに入れてtestそのファイルを実行します。出力:

0.94

しかし、大容量ファイルのパフォーマンスを判断することは不可能です。

関連情報