如何从文件中获取数字并使用 shell 脚本进行计算

如何从文件中获取数字并使用 shell 脚本进行计算

我有一个名为 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':'


使用numsumsudo 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

相关内容