У меня есть файл с именем numbers.txt. Они содержат такие числа, как это
1568
14578
2365
41655
9965
...
...
. Мне нужно вычислить сумму этих чисел. Как я могу это сделать с помощью сценария оболочки ??
Используя awk
awk -F' ' '{for (i=1;i<=NF;i++) {sum+=$i;} print sum}' <your_file> | tail -1
, Если существует другой разделитель, чем space
, используйте -F'<your_delimiter>'
, например: -F':'
Используя numsum
(sudo apt-get install num-utils
)
numsum -r <your_file> | numsum
, Если существует другой разделитель, чем space
, используйте -s <your_delimiter>
, например: -s ':'
Пример
% awk '{for (i=1;i<=NF;i++) {sum+=$i;} print sum}' foo
70131
106625020
% awk '{for (i=1;i<=NF;i++) {sum+=$i;} print sum}' foo | tail -1
106625020
% numsum -r foo | numsum
106625020
% awk '{for (i=1;i<=NF;i++) {sum+=$i;} print sum}' bar | tail -1
70131
% numsum -r foo | numsum
70131
% cat foo
1568 14578 2365 41655 9965
7673 8273923 98273293
% cat bar
1568
14578
2365
41655
9965
Для разделенных от строки входных файлов следующий awk
код работает хорошо:
awk '{s+=$1} END {print s}' numbers.txt
сообщается, что с некоторыми версиями awk
могут быть некоторые неожиданные поведения, если сумма будет больше чем 2 147 483 647.
Относятся к это ТАК ответ и его комментарии.
Если Ваш файл огромен (например, seq 1 100000000 > numbers.txt
), традиционные инструменты начинают разваливаться.
awk '{s+=$1} END {print s}
берет 34, но "0%" RAM (не уверенный, если это точно),perl -nle '$sum += $_ } END { print $sum' numbers.txt
взял 27 и крошечную сумму RAM.pypy
, та же RAM)numsum
было ужасно; это взяло 9m43 s и 14 ГБ RAM для предоставления экспоненциального числа (другие ответили с полными длинными целыми),Альтернатива, которую я предлагаю ответу, который может добавить сто миллионов целые числа через 6,4 секунд...
... Но это записано в C. Легкий C. Никакие странные требования для создания, или градус не должны были понимать это, но действительно необходимо скомпилировать его, и имя файла является hardcoded в него (который Вы могли зафиксировать)...
#include <stdio.h>
int main(void) {
FILE *fp;
char line[100];
unsigned long int total = 0;
fp = fopen("numbers.txt", "r");
while (fgets(line, 100, fp) != NULL) {
total += atoi(line);
}
fclose(fp);
printf("%li\n", total);
return 0;
}
Сохраните это как что-то как add.c
, выполненный make add
и затем ./add
работать.
Используя perl
и принятие разделителя пространства:
perl -MList::Util=sum -ne 'print sum(split())."\n"' numbers.txt
Для a ,
использование разделителя:
perl -MList::Util=sum -ne 'print sum(split(/,/))."\n"' numbers.txt
Но предпочтите эту команду, если они - каждый на своей собственной строке:
perl -nle '$sum += $_ } END { print $sum'
В Python:
python -c "print(sum(int(n) for n in open('f').read().split()))"
где f является файлом (+path) между (единственными) кавычками, например:
python -c "print(sum(int(n) for n in open('/home/jacob/Bureaublad/file.txt').read().split()))"
Разделитель может быть изменен в разделе .split()
. Если, например, разделитель запятая, набор: .split(',')
. По умолчанию числа разделяются обоими \n
и " "
.
open('f').read().split()
читает файл, разделяет его на числа (как строки)
(int(n) for n in...
преобразовывает строки в числа
print(sum(...
наконец, суммирует найденные числа и печатает результат
Результат на файле:
1 2 3 4 5 200 2345
2560
Но также и; с тех пор split()
разделения на \n
также:
1
2
3
4
5
200
2345
2560
Хотя конкуренция с ответом Oli на скорости и ресурсах была бы фатальной ошибкой, ЕСЛИ БЫ файл будет огромен, по крайней мере, на использовании ресурсов, сценарий ниже предложил бы важное улучшение. Хотя сценарий быстрее затем один - лайнер в моем исходном ответе, самое большое улучшение находится на использовании памяти.
#!/usr/bin/env python3
import sys
total = 0
with open(sys.argv[1]) as lines:
for l in lines:
total = total+int(l)
print(total)
Сохраните его как addnumbers.py
, выполните его с текстовым файлом как аргумент:
python3 <script> <file>