Среднее последних N совпадений с использованием awk

Don ' Я не заморачиваюсь с grep . Передайте его напрямую в awk следующим образом:

$ sudo iwlist wlan0 scan | awk -F ':' '/ESSID:/ {print $2;}'
"BTWifi-with-FON"
"BTHub5-FTQN"
"BTWifi-X"
"4GEEOnetouchY800z_2DEB"

Выполняется поиск по регулярному выражению для ESSID: и эта строка разбивается на двоеточие ( -F ':' ), после чего печатается второй элемент этого разбиения ( print $ 2 ).

Или пропустите его через perl :

$ sudo iwlist wlan0 scan | perl -nle '/ESSID:(.*)$/ && print $1'

Это заставит perl запустить команду ( -e ) в каждой строке ввода ( -n ) и добавляет перевод строки в конец каждой строки ( -l ). Команда представляет собой регулярное выражение, которое ищет ESSID: и захватывает оставшуюся строку ( (. *) $ ). Обнаружив это совпадение, он печатает захват ( && print $ 1 ).

-1
19.11.2018, 16:56
4 ответа

Может быть, немного надуманно, но так как 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
28.01.2020, 05:07

Вам это подходит?

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

Однако я не могу сказать, какой будет производительность при работе с огромным файлом.

0
28.01.2020, 05:07

Вам придется использовать круглую таблицу, вот пример кода с последними 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.

0
28.01.2020, 05:07

Я бы использовал для этого 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
1
28.01.2020, 05:07

Теги

Похожие вопросы