В bash я могу выполнить некоторые измерения времени из файла журнала, подобного этому
grep "time:" myLogfile.txt | cut -d' ' -f 3 >> timeMeasurements.txt
#timeMeasurements.txt
2.5
3.5
2.0
...
Теперь я хотел бы вычислить среднее значение из значений в timeMeasurements.txt. Каков самый быстрый способ сделать это в bash? Я знаю, что есть gnuplot и R, но кажется, что нужно написать длинный скрипт для одного из них.
Другой способ, используя 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, который оценивает его по очереди.
Другой способ, используя 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, который оценивает его по очереди.
Другой способ, используя 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, который оценивает его по очереди.
Другой способ, используя 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, который оценивает его по очереди.
Другой способ, используя 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, который оценивает его по очереди.
Другой способ, используя 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, который оценивает его по очереди.
Обязательная версия datamash GNU
$ datamash mean 1 < file
2.6666666666667
ASIDE: похоже, что это действительно должно быть возможно изначально в bc (т.е. без использования оболочки или внешней программы , для циклического ввода входных значений). Реализация GNU bc включает в себя функцию read() - однако, как представляется, сложно затруднить ее обнаружение конца ввода. Лучшее, что я мог бы придумать, это:
#!/usr/bin/bc
scale = 6
while( (x = read()) ) {
s += x
c += 1
}
s/c
quit
, который затем вы можете подключить входной файл к ASIDE , например
$ { cat file; echo '@'; } | ./mean.bc
2.666666
Вы можете использовать awk. Bash сам по себе не очень хорош в математике ...
awk 'BEGIN { lines=0; total=0 } { lines++; total+=$1 } END { print total/lines }' timeMeasurements.txt
Адаптация команды R из этого сообщения U & amp; L:
$ Rscript -e 'd<-scan("stdin", quiet=TRUE)' -e 'cat(mean(d), sep="\n")' < foo
2.666667
Вы можете использовать bc базовый калькулятор в цикле 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. Прочитайте файл по строкам, установив значение в строке как переменную num. Для этого мы используем конструкцию while read -r num; do ... ; done < timeMeasurements.txt. Это будет означать, что мы сделаем что-то для каждой строки файла. Внутри цикла while добавьте переменную count по одной для каждой строки с арифметикой bash ((count++)). Используйте команду bash подстановки $(...) с echo, переданной по каналу bc, чтобы добавить значение переменной num для этой строки файла, к сумме переменной num из всех предыдущих строк. bc используется, поскольку bash не справляется с арифметикой с плавающей запятой.В этот момент цикл заканчивается, переменная count содержит количество измеренных значений времени, переменная суммы содержит сумму измерений времени.
Сначала мы устанавливаем подсчет значений и сумма в виде числа и суммы переменных со значениями 0.Датамаш кажется хорошим вариантом, но даже признавая, что мой ответ может быть излишним, на всякий случай, если вы хотите сделать немного больше, чем просто среднее значение, октава не такая подробная:
$ octave
octave:1> load timeMeasurements.txt
octave:2> mean(timeMeasurements)
ans = 2.6667
Если вы делаете это, помните, что одно и то же среднее может иметь разные типы поведения, поэтому стандартное отклонение обычно также имеет значение:
octave:3> std(timeMeasurements)
ans = 0.76376
или даже простая гистограмма проста: [ ! d2]
octave:4> hist(timeMeasurements)
Кроме того, я думаю, что datamash не находится в репозиториях apt-get для trusty, только для более новых версий.
Oneliner, для более дружественные сценарии:
octave -q --eval "m = load(\"timeMeasurements.txt\"); mean(m)"
Вы можете использовать bc базовый калькулятор в цикле 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. Прочитайте файл по строкам, установив значение в строке как переменную num. Для этого мы используем конструкцию while read -r num; do ... ; done < timeMeasurements.txt. Это будет означать, что мы сделаем что-то для каждой строки файла. Внутри цикла while добавьте переменную count по одной для каждой строки с арифметикой bash ((count++)). Используйте команду bash подстановки $(...) с echo, переданной по каналу bc, чтобы добавить значение переменной num для этой строки файла, к сумме переменной num из всех предыдущих строк. bc используется, поскольку bash не справляется с арифметикой с плавающей запятой.В этот момент цикл заканчивается, переменная count содержит количество измеренных значений времени, переменная суммы содержит сумму измерений времени.
Сначала мы устанавливаем подсчет значений и сумма в виде числа и суммы переменных со значениями 0.Адаптация команды R из этого сообщения U & amp; L:
$ Rscript -e 'd<-scan("stdin", quiet=TRUE)' -e 'cat(mean(d), sep="\n")' < foo
2.666667
Датамаш кажется хорошим вариантом, но даже признавая, что мой ответ может быть излишним, на всякий случай, если вы хотите сделать немного больше, чем просто среднее значение, октава не такая подробная:
$ octave
octave:1> load timeMeasurements.txt
octave:2> mean(timeMeasurements)
ans = 2.6667
Если вы делаете это, помните, что одно и то же среднее может иметь разные типы поведения, поэтому стандартное отклонение обычно также имеет значение:
octave:3> std(timeMeasurements)
ans = 0.76376
или даже простая гистограмма проста: [ ! d2] octave:4> hist(timeMeasurements)
Кроме того, я думаю, что datamash не находится в репозиториях apt-get для trusty, только для более новых версий.
Oneliner, для более дружественные сценарии:
octave -q --eval "m = load(\"timeMeasurements.txt\"); mean(m)"
Обязательная версия datamash GNU
$ datamash mean 1 < file
2.6666666666667
ASIDE: похоже, что это действительно должно быть возможно изначально в bc (т.е. без использования оболочки или внешней программы , для циклического ввода входных значений). Реализация GNU bc включает в себя функцию read() - однако, как представляется, сложно затруднить ее обнаружение конца ввода. Лучшее, что я мог бы придумать, это:
#!/usr/bin/bc
scale = 6
while( (x = read()) ) {
s += x
c += 1
}
s/c
quit
, который вы можете подключить входной файл к ASIDE , например
$ { cat file; echo '@'; } | ./mean.bc
2.666666
Вы можете использовать awk. Bash сам по себе не очень хорош в математике ...
awk 'BEGIN { lines=0; total=0 } { lines++; total+=$1 } END { print total/lines }' timeMeasurements.txt
Вы можете использовать bc базовый калькулятор в цикле 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. Прочитайте файл по строкам, установив значение в строке как переменную num. Для этого мы используем конструкцию while read -r num; do ... ; done < timeMeasurements.txt. Это будет означать, что мы сделаем что-то для каждой строки файла. Внутри цикла while добавьте переменную count по одной для каждой строки с арифметикой bash ((count++)). Используйте команду bash подстановки $(...) с echo, переданной по каналу bc, чтобы добавить значение переменной num для этой строки файла, к сумме переменной num из всех предыдущих строк. bc используется, поскольку bash не справляется с арифметикой с плавающей запятой.В этот момент цикл заканчивается, переменная count содержит количество измеренных значений времени, переменная суммы содержит сумму измерений времени.
Сначала мы устанавливаем подсчет значений и сумма в виде числа и суммы переменных со значениями 0.Адаптация команды R из этого сообщения U & amp; L:
$ Rscript -e 'd<-scan("stdin", quiet=TRUE)' -e 'cat(mean(d), sep="\n")' < foo
2.666667
Датамаш кажется хорошим вариантом, но даже признавая, что мой ответ может быть излишним, на всякий случай, если вы хотите сделать немного больше, чем просто среднее значение, октава не такая подробная:
$ octave
octave:1> load timeMeasurements.txt
octave:2> mean(timeMeasurements)
ans = 2.6667
Если вы делаете это, помните, что одно и то же среднее может иметь разные типы поведения, поэтому стандартное отклонение обычно также имеет значение:
octave:3> std(timeMeasurements)
ans = 0.76376
или даже простая гистограмма проста: [ ! d2] octave:4> hist(timeMeasurements)
Кроме того, я думаю, что datamash не находится в репозиториях apt-get для trusty, только для более новых версий.
Oneliner, для более дружественные сценарии:
octave -q --eval "m = load(\"timeMeasurements.txt\"); mean(m)"
Обязательная версия datamash GNU
$ datamash mean 1 < file
2.6666666666667
ASIDE: похоже, что это действительно должно быть возможно изначально в bc (т.е. без использования оболочки или внешней программы , для циклического ввода входных значений). Реализация GNU bc включает в себя функцию read() - однако, как представляется, сложно затруднить ее обнаружение конца ввода. Лучшее, что я мог бы придумать, это:
#!/usr/bin/bc
scale = 6
while( (x = read()) ) {
s += x
c += 1
}
s/c
quit
, который вы можете подключить входной файл к ASIDE , например
$ { cat file; echo '@'; } | ./mean.bc
2.666666
Вы можете использовать awk. Bash сам по себе не очень хорош в математике ...
awk 'BEGIN { lines=0; total=0 } { lines++; total+=$1 } END { print total/lines }' timeMeasurements.txt
Вы можете использовать bc базовый калькулятор в цикле 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. Прочитайте файл по строкам, установив значение в строке как переменную num. Для этого мы используем конструкцию while read -r num; do ... ; done < timeMeasurements.txt. Это будет означать, что мы сделаем что-то для каждой строки файла. Внутри цикла while добавьте переменную count по одной для каждой строки с арифметикой bash ((count++)). Используйте команду bash подстановки $(...) с echo, переданной по каналу bc, чтобы добавить значение переменной num для этой строки файла, к сумме переменной num из всех предыдущих строк. bc используется, поскольку bash не справляется с арифметикой с плавающей запятой.В этот момент цикл заканчивается, переменная count содержит количество измеренных значений времени, переменная суммы содержит сумму измерений времени.
Сначала мы устанавливаем подсчет значений и сумма в виде числа и суммы переменных со значениями 0.Адаптация команды R из этого сообщения U & amp; L:
$ Rscript -e 'd<-scan("stdin", quiet=TRUE)' -e 'cat(mean(d), sep="\n")' < foo
2.666667
Датамаш кажется хорошим вариантом, но даже признавая, что мой ответ может быть излишним, на всякий случай, если вы хотите сделать немного больше, чем просто среднее значение, октава не такая подробная:
$ octave
octave:1> load timeMeasurements.txt
octave:2> mean(timeMeasurements)
ans = 2.6667
Если вы делаете это, помните, что одно и то же среднее может иметь разные типы поведения, поэтому стандартное отклонение обычно также имеет значение:
octave:3> std(timeMeasurements)
ans = 0.76376
или даже простая гистограмма проста: [ ! d2] octave:4> hist(timeMeasurements)
Кроме того, я думаю, что datamash не находится в репозиториях apt-get для trusty, только для более новых версий.
Oneliner, для более дружественные сценарии:
octave -q --eval "m = load(\"timeMeasurements.txt\"); mean(m)"
Обязательная версия datamash GNU
$ datamash mean 1 < file
2.6666666666667
ASIDE: похоже, что это действительно должно быть возможно изначально в bc (т.е. без использования оболочки или внешней программы , для циклического ввода входных значений). Реализация GNU bc включает в себя функцию read() - однако, как представляется, сложно затруднить ее обнаружение конца ввода. Лучшее, что я мог бы придумать, это:
#!/usr/bin/bc
scale = 6
while( (x = read()) ) {
s += x
c += 1
}
s/c
quit
, который вы можете подключить входной файл к ASIDE , например
$ { cat file; echo '@'; } | ./mean.bc
2.666666
Вы можете использовать awk. Bash сам по себе не очень хорош в математике ...
awk 'BEGIN { lines=0; total=0 } { lines++; total+=$1 } END { print total/lines }' timeMeasurements.txt
Вы можете использовать bc базовый калькулятор в цикле 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. Прочитайте файл по строкам, установив значение в строке как переменную num. Для этого мы используем конструкцию while read -r num; do ... ; done < timeMeasurements.txt. Это будет означать, что мы сделаем что-то для каждой строки файла. Внутри цикла while добавьте переменную count по одной для каждой строки с арифметикой bash ((count++)). Используйте команду bash подстановки $(...) с echo, переданной по каналу bc, чтобы добавить значение переменной num для этой строки файла, к сумме переменной num из всех предыдущих строк. bc используется, поскольку bash не справляется с арифметикой с плавающей запятой.В этот момент цикл заканчивается, переменная count содержит количество измеренных значений времени, переменная суммы содержит сумму измерений времени.
Сначала мы устанавливаем подсчет значений и сумма в виде числа и суммы переменных со значениями 0.Адаптация команды R из этого сообщения U & amp; L:
$ Rscript -e 'd<-scan("stdin", quiet=TRUE)' -e 'cat(mean(d), sep="\n")' < foo
2.666667
Датамаш кажется хорошим вариантом, но даже признавая, что мой ответ может быть излишним, на всякий случай, если вы хотите сделать немного больше, чем просто среднее значение, октава не такая подробная:
$ octave
octave:1> load timeMeasurements.txt
octave:2> mean(timeMeasurements)
ans = 2.6667
Если вы делаете это, помните, что одно и то же среднее может иметь разные типы поведения, поэтому стандартное отклонение обычно также имеет значение:
octave:3> std(timeMeasurements)
ans = 0.76376
или даже простая гистограмма проста: [ ! d2] octave:4> hist(timeMeasurements)
Кроме того, я думаю, что datamash не находится в репозиториях apt-get для trusty, только для более новых версий.
Oneliner, для более дружественные сценарии:
octave -q --eval "m = load(\"timeMeasurements.txt\"); mean(m)"
Обязательная версия datamash GNU
$ datamash mean 1 < file
2.6666666666667
ASIDE: похоже, что это действительно должно быть возможно изначально в bc (т.е. без использования оболочки или внешней программы , для циклического ввода входных значений). Реализация GNU bc включает в себя функцию read() - однако, как представляется, сложно затруднить ее обнаружение конца ввода. Лучшее, что я мог бы придумать, это:
#!/usr/bin/bc
scale = 6
while( (x = read()) ) {
s += x
c += 1
}
s/c
quit
, который вы можете подключить входной файл к ASIDE , например
$ { cat file; echo '@'; } | ./mean.bc
2.666666