Média dos últimos n resultados usando awk

0

Eu tenho um arquivo crescente. enquanto vai escrever o log do meu processo de candidatura. Nesse arquivo, há um log para "velocidade" como abaixo

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

Eu tentei o código abaixo para obter o valor médio de velocidade.

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

é possível obter a média das últimas 120 entradas? Eu tentei com grep e tail, mas demorou muito tempo desde que é um arquivo crescente.

    
por msp9011 19.11.2018 / 15:56

4 respostas

2

Um pouco improvável, talvez, mas como tac irá lseek do final do arquivo momentâneo, você definirá o ponto necessário no tempo e a partir daí voltará até 120 velocidades encontradas:

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

Ou para gerenciar entradas que podem ter menos de 120 ocorrências do padrão:

tac file | awk '/speed/ {SUM += $2; if (++C == 120) exit}
                END {if (C) print SUM/C}'
    
por 19.11.2018 / 16:34
1

Eu usaria perl ao invés de awk para isso: bastante simples de lembrar apenas as últimas 120 velocidades:

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
    
por 19.11.2018 / 16:19
0

Você terá que usar uma tabela circular, aqui está um exemplo de código com os últimos 5 valores

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 ;
}

você pode testar em um arquivo de amostra (ou na linha de comando, valores a serem inseridos na linha de comando).

awk -f avg.awk sample.txt

depois substitua 5 por 120 e printf linha pelo que combina com você.

observe que +=$2 ignorará o trailling x .

    
por 19.11.2018 / 16:10
0

Isso funciona para você?

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

Acabei de colocar sua entrada em um arquivo chamado test e executei isso. Saída:

0.94

Não é possível dizer qual será o desempenho em um arquivo enorme.

    
por 19.11.2018 / 16:00

Tags