Как вычислить очень большие числа с помощью bc в bash

У меня есть файл с 1800 строками, которые выглядят так

600.76
600.66
700.44
566.66
Ect..

Я сделал скрипт bash для вычисления среднего значения.

Теперь я сначала создал переменную для подсчета общего количества строк столбца, например:

Lines="$(awk 'END{print NR}' file.txt)"

Затем еще одна переменная для суммы этого столбца, например:

Sum="$(awk '{s+1=$1}END {print s}' file.txt)"

Наконец, я нахожу среднее значение следующим образом:

Echo "scale=2 ; $Sum / $Lines" | bc

При включенной отладке возвращается:

+echo 'scale=2 ; 1.72161e+06 / 1800'
(Standard_1): syntax error

Теперь я понимаю, что bc не использует научную запись, но как мне обойти это.

Я согласен с короткой передачей десятичной дроби, ограничивая ее 2 или 3 знаками.


person theloosegoos    schedule 31.01.2017    source источник
comment
Почему бы просто не использовать awk?   -  person dawg    schedule 31.01.2017
comment
как насчет просто awk '{sum+=$1}END{print sum/NR}'?   -  person twalberg    schedule 31.01.2017
comment
@twallberg awk возвращает экспоненциальное представление, когда ответ становится слишком большим. Какая изначальная проблема   -  person theloosegoos    schedule 31.01.2017
comment
@theloosegoos Возможно, awk '{sum+=$1}END{printf "%f\n", sum/NR} даст лучшие результаты. awk имеет реализацию printf, которая имитирует многие (но не все) функции версии C...   -  person twalberg    schedule 01.02.2017
comment
@theloosegoos Есть ли строки во входном файле в экспоненциальном представлении?   -  person Ian Petts    schedule 01.02.2017
comment
Нет, я говорю, что файл имеет только один столбец, и это число вроде этого 857,54. Есть 1800 строк, похожих на это. Когда вы суммируете файл, результат находится в экспоненциальном представлении. Там, когда я пытаюсь передать это bc для некоторого деления, он выдает ошибку.   -  person theloosegoos    schedule 01.02.2017


Ответы (2)


Необязательно использовать awk. Простой oneliner может сделать эту работу.

echo "scale=2; ("$(paste -sd+ file.txt)")"/$(wc -l <file.txt)|bc 
person Ipor Sircer    schedule 31.01.2017
comment
Это по-прежнему отправляет bc в ошибку, он не может обрабатывать научную нотацию, это происходит, когда ответ превышает определенное значение. - person theloosegoos; 31.01.2017

Используйте bc -l как для суммирования, так и для окончательного деления:

sum=0
count=0
while read number; do
  number=$(printf "%f\n" $number) # get rid of scientific notation
  sum=$(echo "$sum" '+' "$number" | bc -l)
  count=$((count + 1))
done < input
avg=$(echo $sum / $count | bc -l)
echo $avg
person gudok    schedule 31.01.2017
comment
Это приведет меня к той же ошибке, потому что сумма файла слишком велика, она выражена в экспоненциальном представлении. - person theloosegoos; 31.01.2017
comment
@theloosegoos Нет, не будет. bc не использует экспоненциальное представление. Это калькулятор произвольной точности. - person gudok; 31.01.2017
comment
корень проблемы заключается в добавлении столбца моего файла. Сумма настолько велика, что выражается в научных обозначениях. Поэтому, когда я передаю сумму столбца в bc, он выдает ошибку, потому что не принимает запись. - person theloosegoos; 01.02.2017
comment
@theloosegoos, можете ли вы предоставить входной файл? - person gudok; 01.02.2017
comment
это самый первый пример в посте. Помимо всего лишь первой из 1800 строк - person theloosegoos; 01.02.2017
comment
@theloosegoos, bc никогда не использует научную запись. Если вы все еще получаете ошибку, то я предполагаю, что одно из входных чисел уже представлено в экспоненциальном представлении. Вы можете использовать printf для преобразования числа обратно в обычную запись. Я обновил код в своем посте. - person gudok; 01.02.2017