使用 awk 计算最后 n 场比赛的平均值

使用 awk 计算最后 n 场比赛的平均值

我的文件越来越大。 while 会写我的申请过程的日志。在该文件中,有一个“速度”日志,如下所示

(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

为此,我会使用 perl 而不是 awk:非常简单地记住最后 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

但无法判断大文件的性能。

相关内容