Как я вычисляю среднее из данных ASCII-файла в ударе?

В ударе я могу grep измерения некоторого времени от файла журнала как это

grep "time:" myLogfile.txt | cut -d' ' -f 3 >> timeMeasurements.txt

#timeMeasurements.txt
2.5
3.5
2.0
...

Теперь я хотел бы вычислить среднее значение из значений в timeMeasurements.txt. Что самый быстрый путь состоит в том, чтобы сделать это в ударе?
Я знаю, что существует gnuplot и R, но кажется, что нужно записать некоторый длинный сценарий для любого на них.

7
задан 5 April 2017 в 19:41

6 ответов

Иначе, с помощью sed и bc:

sed 's/^/n+=1;x+=/;$ascale=1;x/n' timemeasurements.txt | bc

sed выражение преобразовывает вход во что-то вроде этого:

n+=1;x+=2.5
n+=1;x+=3.5
n+=1;x+=2.0
scale=1;x/n

Это передается по каналу к bc, который оценивает его линию за линией.

11
ответ дан 23 November 2019 в 06:07

Вы могли использовать awk. Сам Bash не очень хорош в математике...

awk 'BEGIN { lines=0; total=0 } { lines++; total+=$1 } END { print total/lines }' timeMeasurements.txt

Примечания

  • lines=0; total=0 переменные набора к 0
  • lines++ увеличение lines одним для каждой строки
  • total+=$1 добавляет значение в каждой строке к рабочему общему количеству
  • print total/lines при выполнении разделите общее количество на количество значений
12
ответ дан 23 November 2019 в 06:07

Адаптация команды R от этот U& L сообщение :

$ Rscript -e 'd<-scan("stdin", quiet=TRUE)' -e 'cat(mean(d), sep="\n")' < foo
2.666667
8
ответ дан 23 November 2019 в 06:07

datamash каждый кажется хорошим вариантом, но даже подтверждая, что мой ответ может быть излишеством, на всякий случай Вы хотите сделать немного больше, чем просто среднее, октава, не таким образом подробный:

$ octave
octave:1> load timeMeasurements.txt 
octave:2> mean(timeMeasurements)
ans =  2.6667

при выполнении средств помните, что то же означает, мог прибыть из совсем других поведений, таким образом, стандартное отклонение обычно также релевантно:

octave:3> std(timeMeasurements)
ans =  0.76376

или даже простая гистограмма легко сделать:

octave:4> hist(timeMeasurements)

кроме того, я думаю, что datamash не находится в Кв. - получают репозитории для надежного человека, только для более новых версий.

Редактирование:

Острота, для большего количества благоприятных для сценария использований:

octave -q --eval "m = load(\"timeMeasurements.txt\"); mean(m)"
4
ответ дан 23 November 2019 в 06:07

Обязательный GNU datamash версия

$ datamash mean 1 < file
2.6666666666667

В СТОРОНЕ: такое чувство, что это действительно должно быть возможно исходно в bc (т.е. не используя оболочку или внешнюю программу, для цикличного выполнения по входным значениям). GNU bc реализация включает a read() функция - однако это, кажется, разочаровывающе трудно заставить это обнаруживать конец входа. Лучшее, которое я мог придумать:

#!/usr/bin/bc

scale = 6
while( (x = read()) ) {
  s += x
  c += 1
}
s/c
quit

который можно затем передать вход файла по каналу к тому, если Вы завершаете вход с любым нечисловым символом, например.

$ { cat file; echo '@'; } | ./mean.bc
2.666666
13
ответ дан 23 November 2019 в 06:07

Можно использовать bc основной калькулятор, в a while цикл с read:

count=0; sum=0; while read -r num; do ((count++)); sum=$(echo "$sum + $num" | bc); done < timeMeasurement.txt; echo "scale=2; $sum / $count" | bc -l

Или больше четко:

count=0
sum=0
while read -r num
do
  ((count++))
  sum=$(echo "$sum + $num" | bc)
done < timeMeasurement.txt
echo "scale=2; $sum / $count" | bc -l

Объяснение:

  • Сначала мы устанавливаем количество значений и суммарного итога, поскольку переменные считают и суммируют со значениями 0.
  • Считайте файл линию за линией, установив значение в строке как переменная цифра. Мы используем конструкцию while read -r num; do ... ; done < timeMeasurements.txt сделать это. Это будет означать, что мы сделаем что-то для каждой строки файла.
  • В цикле с условием продолжения увеличьте переменную количества одной для каждой строки с арифметикой удара ((count++)).
  • Используйте замену команды удара $(...) с echo переданный по каналу к bc добавить значение цифровой переменной для этой строки файла, к сумме цифровой переменной от всех предыдущих строк. bc используется, поскольку удар не справляется хорошо с арифметикой с плавающей точкой.

В этой точке концы цикла переменная количества содержит количество измерительных значений времени, переменная суммы содержит сумму измерений времени.

  • Использовать echo с нашими переменными для создания среднего вычисления, которое передается bc. scale=2 часть говорит bc сколько значащих цифр для отображения.
5
ответ дан 23 November 2019 в 06:07

Другие вопросы по тегам:

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