如何对文件中的行上的数字求和


24

我有一个看起来像这样的文件:

1
3
4
1
4
3
1
2

我如何才能找到总数(即1 + 3 + 4 + 1 + 4 + 3 + 1 + 2 = 19)?


1
就上下文而言,我计算的是从Stack Exchange API在Ask Ubuntu上获得的徽章数量。
蒂姆(Tim)

cat badges.json | grep -o '"award_count":[0-9],"rank":"gold"' | grep -o [0-9]
蒂姆(Tim)

尽管我现在意识到API具有一种badge_count方法。
蒂姆(Tim)

如果您要从API计数徽章,则用于查询API的语言无法做到这一点(python,javascript)?
Braiam'6

Answers:


42

bc从中paste获得一些帮助,以+分隔符将行合并为一条:

paste -sd+ file.txt | bc

要使用grep(或任何其他命令)的输出代替静态文件,请将grep的STDOUT 传递给的STDIN paste

grep .... | paste -sd+ | bc

例:

% cat file.txt            
1
3
4
1
4
3
1
2

% paste -sd+ file.txt | bc
19

% grep . file.txt | paste -sd+ | bc
19

如果必须使用bash,则可以使用数组保存文件内容,然后遍历元素,或者可以逐行读取文件并为每一行求和,第二种方法会更有效:

$ time { nums=$(<file.txt); for i in ${nums[@]}; do (( sum+=i )); done; echo $sum ;}
19

real    0m0.002s
user    0m0.000s
sys 0m0.000s

$ time { while read i; do (( sum+=i )); done <file.txt; echo $sum ;}
19

real    0m0.000s
user    0m0.000s
sys 0m0.000s

嗯,很好。抱歉改变这个问题:我可以修改一下以接受grep输出(或使其像一行cat file.txt | bc吗?
Tim

@Tim检查我的编辑
heemayl

Ta,那很简单!
蒂姆(Tim)

2
直到我在我必须使用的另一个答案中发现时,stdin的方式对我才有效paste -sd+ -。请修改。
Xerus

19

您也可以使用awk。要计算* .txt文件中包含单词“ hello” 的总行数:

grep -ch 'hello' *.txt | awk '{n += $1}; END{print n}'

要简单地对文件中的数字求和:

awk '{n += $1}; END{print n}' file.txt

但是,如果该行的值为“ 4”,它将不会计数为4。它将计算1
蒂姆

不,它会计算4
CrazyApe84

我想要一个文件中的总数。这样做吗?
蒂姆(Tim

我以为您将问题更改为grep的输出。我在做一些假设。我将添加如何简单地对文件中的值求和。
CrazyApe84 '16

2
是的 答案确实与heemayl相同,但是它使用awk代替了paste和bc,最终提供了更多的灵活性。尽管如此,他的回答还是不错的,他是第一位的,所以他值得您投票!
CrazyApe84 '16

7

numsum从包装中使用num-utils

(您可能需要sudo apt-get install num-utils

numsum默认情况下,该命令执行所需的操作;

$ numsum file.txt 
19

从逐行读取测试编号stdin

$ printf '
1 
3
4
1
4
3
1
2' | numsum
19

或单行阅读:

$ printf '1 3 4 1 4 3 1 2' | numsum -r
19


更多实用程序

该软件包还包含一些其他的用于数字处理的实用程序,这些实用程序应该是众所周知的:

numaverage   - find the average of the numbers, or the mode or median
numbound     - find minimum of maximum of all lines
numgrep      - to find numbers matching ranges or sets
numinterval  - roughly like the first derivative
numnormalize - normalize numbers to an interval, like 0-1
numrandom    - random numbers from ranges or sets, eg odd.  
numrange     - similar to seq
numround     - round numbers up, down or to nearest

还有一个更通用的计算器命令numprocess
该命令将命令行中的表达式应用于输入行中的数字。


1

您可以使用awk本地linux应用程序,用于扫描和处理每行带有某种模式的文件。对于您的问题,这将产生您想要的:

awk 'BEGIN { sum=0 } { sum+=$1 } END {print sum }' file.txt

管道也可以接受:

cat file.txt | awk 'BEGIN { sum=0 } { sum+=$1 } END {print sum }'

无需BEGIN{}阻止,请参见CrazyApe84的答案
terdon

解决这个问题是多余的,但由于教学的目的,我倾向于包括它。
gwarah

但是它教什么呢?它对每个问题都是多余的,awk不是C,您在使用它之前不需要设置变量。尝试awk 'BEGIN{print c+=1}'
terdon

BEGIN {}块不仅用于初始化变量。它参与设计规范。因此,在某些问题上可能是需要的。
gwarah

0

这是bash脚本的相当简单的用法。

SUM=0; for line in `cat file.txt`; do SUM=$((SUM + line)); done

与当前解决方案相比,这要简单得多且工具集也要简约。
挪威

0

Perl解决方案:

$ perl -lnae '$c+=$_;END{print $c}' input.txt                                                                            
19

上面可以汇总多个文件中的所有数字:

$ perl -lnae '$c+=$_;END{print $c}' input.txt input2.txt                                                                 
34

对于希望在单个文件中查看数字总和的命令行上提供的多个文件,可以执行以下操作:

$ perl -lnae '$c+=$_;if(eof){printf("%d %s\n",$c,$ARGV);$c=0}' input.txt input2.txt                                      
19 input.txt
15 input2.txt


0

一种简单的方法是使用外壳程序的内置功能:

SUM=0; while read N; do SUM=$((SUM+N)); done </path/to/file
echo $SUM

这将按行读取您的文件,进行汇总并打印结果。

如果要使用管道并且仅使用第一行,则它的工作方式如下:

SUM=0
your_command | while read -r LINE; do for N in $LINE; do break; done; SUM=$((SUM+N)); done
echo $SUM

获取第一个元素是这样完成的:

LIST="foo bar baz"
for OBJ in $LIST; do break; done
echo $OBJ

foo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.