我有一个名为 numbers.txt 的文件。其中包含一些像这样的数字
1568
14578
2365
41655
9965
...
...
我需要计算这些数字的总和。如何使用 shell 脚本来计算总和?
答案1
如果您的文件巨大的(例如seq 1 100000000 > numbers.txt
),传统工具开始崩溃。
awk '{s+=$1} END {print s}
耗时 34 秒,但 RAM 为“0%”(不确定是否准确)perl -nle '$sum += $_ } END { print $sum' numbers.txt
耗时 27 秒和少量 RAM。- 雅各布的蟒蛇耗时 47 秒,使用 6GB RAM(使用
pypy
相同 RAM 运行时耗时 23 秒) numsum
曾是可怕;它花费了 9 分 43 秒和 14GB 的 RAM 来给出一个指数(其他人则用完整的长整数回复)- 纯 Bash 需要花很长时间才能完成对它们的 for 循环,所以我不会尝试
我提供的替代方案在 6.4 秒内添加一亿个整数...
...但是它是用 C 语言编写的。简单的 C 语言。没有奇怪的构建要求,也没有理解它的学位,但你必须编译它并且文件名是硬编码到其中的(你可以修复)...
#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
运行。
答案2
使用perl
并假设空格分隔符:
perl -MList::Util=sum -ne 'print sum(split())."\n"' numbers.txt
对于,
分隔符的使用:
perl -MList::Util=sum -ne 'print sum(split(/,/))."\n"' numbers.txt
但更喜欢这个命令如果它们各自在一行上:
perl -nle '$sum += $_ } END { print $sum'
答案3
使用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
答案4
使用 bc :
paste -sd"+" file | bc