Как я могу быстро сложить все числа в файле? - PullRequest
174 голосов
/ 24 апреля 2010

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

34
42
11
6
2
99
...

Я хочу написать скрипт, который будет печатать сумму всех чисел в файле. У меня есть решение, но оно не очень эффективно. (Запуск занимает несколько минут.) Я ищу более эффективное решение. Есть предложения?

Ответы [ 28 ]

3 голосов
/ 22 августа 2013

Вот решение с использованием python с выражением генератора. Протестировано с миллионами чисел на моем старом ноутбуке

time python -c "import sys; print sum((float(l) for l in sys.stdin))" < file

real    0m0.619s
user    0m0.512s
sys     0m0.028s
3 голосов
/ 23 февраля 2013

Просто для удовольствия, давайте сделаем это с PDL , математическим движком Perl!

perl -MPDL -E 'say rcols(shift)->sum' datafile

rcols считывает столбцы в матрицу (в данном случае 1D), а sum (неожиданность) суммирует все элементы матрицы.

3 голосов
/ 23 февраля 2013
cat nums | perl -ne '$sum += $_ } { print $sum'

(аналогично ответу Брайана Д. Фоя, без 'END')

2 голосов
/ 13 сентября 2015

Более кратко:

# Ruby
ruby -e 'puts open("random_numbers").map(&:to_i).reduce(:+)'

# Python
python -c 'print(sum(int(l) for l in open("random_numbers")))'
2 голосов
/ 13 марта 2014
$ perl -MList::Util=sum -le 'print sum <>' nums.txt
2 голосов
/ 24 апреля 2010
sed ':a;N;s/\n/+/;ta' file|bc
2 голосов
/ 03 ноября 2017

Perl 6

say sum lines
~$ perl6 -e '.say for 0..1000000' > test.in

~$ perl6 -e 'say sum lines' < test.in
500000500000
1 голос
/ 11 мая 2014

с рубином:

ruby -e "File.read('file.txt').split.inject(0){|mem, obj| mem += obj.to_f}"
1 голос
/ 24 апреля 2010

Я не проверял это, но оно должно работать:

cat f | tr "\n" "+" | sed 's/+$/\n/' | bc

Возможно, вам придется добавить "\ n" в строку перед bc (как через echo), если bc не обрабатывает EOF и EOL ...

1 голос
/ 25 октября 2012

еще один для развлечения

sum=0;for i in $(cat file);do sum=$((sum+$i));done;echo $sum

или только другой удар

s=0;while read l; do s=$((s+$l));done<file;echo $s

Но решение awk, вероятно, лучше, поскольку оно наиболее компактно.

...