Linux 如何快速求和文件中的所有数字?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2702564/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 19:58:07  来源:igfitidea点击:

How can I quickly sum all numbers in a file?

linuxperlbashshellawk

提问by Mark Roberts

I have a file which contains several thousand numbers, each on it's own line:

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

34
42
11
6
2
99
...

I'm looking to write a script which will print the sum of all numbers in the file. I've got a solution, but it's not very efficient. (It takes several minutes to run.) I'm looking for a more efficient solution. Any suggestions?

我正在寻找编写一个脚本来打印文件中所有数字的总和。我有一个解决方案,但效率不高。(运行需要几分钟。)我正在寻找更有效的解决方案。有什么建议?

采纳答案by brian d foy

For a Perl one-liner, it's basically the same thing as the awksolution in Ayman Hourieh's answer:

对于 Perl one-liner,它与Ayman Hourieh 的回答中awk解决方案基本相同:

 % perl -nle '$sum += $_ } END { print $sum'

If you're curious what Perl one-liners do, you can deparse them:

如果您对 Perl 单行程序的功能感到好奇,您可以解析它们:

 %  perl -MO=Deparse -nle '$sum += $_ } END { print $sum'

The result is a more verbose version of the program, in a form that no one would ever write on their own:

结果是程序的一个更冗长的版本,以一种没有人会自己编写的形式:

BEGIN { $/ = "\n"; $\ = "\n"; }
LINE: while (defined($_ = <ARGV>)) {
    chomp $_;
    $sum += $_;
}
sub END {
    print $sum;
}
-e syntax OK

Just for giggles, I tried this with a file containing 1,000,000 numbers (in the range 0 - 9,999). On my Mac Pro, it returns virtually instantaneously. That's too bad, because I was hoping using mmapwould be really fast, but it's just the same time:

只是为了傻笑,我用一个包含 1,000,000 个数字(在 0 - 9,999 范围内)的文件进行了尝试。在我的 Mac Pro 上,它几乎立即恢复。这太糟糕了,因为我希望使用mmap会非常快,但它只是在同一时间:

use 5.010;
use File::Map qw(map_file);

map_file my $map, $ARGV[0];

$sum +=  while $map =~ m/(\d+)/g;

say $sum;

回答by Stefan Kendall

I don't know if you can get a lot better than this, considering you need to read through the whole file.

考虑到您需要通读整个文件,我不知道您是否可以获得比这更好的东西。

$sum = 0;
while(<>){
   $sum += $_;
}
print $sum;

回答by Ayman Hourieh

You can use awk:

您可以使用 awk:

awk '{ sum +=  } END { print sum }' file

回答by frankc

Just to be ridiculous:

只是为了可笑:

cat f | tr "\n" "+" | perl -pne chop | R --vanilla --slave

回答by Paused until further notice.

This is straight Bash:

这是直接的 Bash:

sum=0
while read -r line
do
    (( sum += line ))
done < file
echo $sum

回答by DVK

I have not tested this but it should work:

我还没有测试过这个,但它应该可以工作:

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

You might have to add "\n" to the string before bc (like via echo) if bc doesn't treat EOF and EOL...

如果 bc 不处理 EOF 和 EOL,您可能必须在 bc 之前的字符串中添加“\n”(如通过 echo)...

回答by ghostdog74

sed ':a;N;s/\n/+/;ta' file|bc

回答by lhf

Here's another one-liner

这是另一个单线

( echo 0 ; sed 's/$/ +/' foo ; echo p ) | dc

This assumes the numbers are integers. If you need decimals, try

这假设数字是整数。如果您需要小数,请尝试

( echo 0 2k ; sed 's/$/ +/' foo ; echo p ) | dc

Adjust 2 to the number of decimals needed.

将 2 调整为所需的小数位数。

回答by nickjb

Another for fun

另一个好玩的

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

or another bash only

或仅其他 bash

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

But awk solution is probably best as it's most compact.

但是 awk 解决方案可能是最好的,因为它最紧凑。

回答by ruben2020

Here's another:

这是另一个:

open(FIL, "a.txt");

my $sum = 0;
foreach( <FIL> ) {chomp; $sum += $_;}

close(FIL);

print "Sum = $sum\n";