我有一个包含数千个数字的文件,每个数字都在自己的行上:

34
42
11
6
2
99
...

我想写一个脚本,它将打印文件中所有数字的总和。我有一个解决办法,但不是很有效。(运行需要几分钟。)我在寻找一个更有效的解决方案。有什么建议吗?


当前回答

C总是以速度取胜:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    ssize_t read;
    char *line = NULL;
    size_t len = 0;
    double sum = 0.0;

    while (read = getline(&line, &len, stdin) != -1) {
        sum += atof(line);
    }

    printf("%f", sum);
    return 0;
}

1M数字的计时(与我的python答案相同的机器/输入):

$ gcc sum.c -o sum && time ./sum < numbers 
5003371677.000000
real    0m0.188s
user    0m0.180s
sys     0m0.000s

其他回答

cat nums | perl -ne '$sum += $_ } { print $sum'

(和brian d foy的回答一样,没有“END”)

只是为了好玩,让我们用PDL (Perl的数组数学引擎)来做!

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

rcols将列读入矩阵(在本例中为1D), sum (surprise)对矩阵中的所有元素求和。

对于这样的任务,我更喜欢使用GNU数据集,因为它比perl或awk更简洁易读。例如

datamash sum 1 < myfile

其中1表示数据的第一列。

我更喜欢用R来表示:

$ R -e 'sum(scan("filename"))'

C总是以速度取胜:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    ssize_t read;
    char *line = NULL;
    size_t len = 0;
    double sum = 0.0;

    while (read = getline(&line, &len, stdin) != -1) {
        sum += atof(line);
    }

    printf("%f", sum);
    return 0;
}

1M数字的计时(与我的python答案相同的机器/输入):

$ gcc sum.c -o sum && time ./sum < numbers 
5003371677.000000
real    0m0.188s
user    0m0.180s
sys     0m0.000s