2017-06-22 14 views
1

我正在写一个解析器,并且必须有一些特殊的东西。我正在尝试不使用Python,但我可能必须在这一点上。在整数列中每5行加起来BASH

由于看起来像这样的STDOUT:

1 
0 
2 
3 
0 
0 
1 
0 
0 
2 
0 
3 
0 
4 
0 
5 
0 
2 
. 
. 
. 

有关100,000行。我需要做的就是添加了每5,就像这样:

1 - start 
0 | 
2 | - 6 
3 | 
0 - end 
0 - start 
1 | 
0 | - 3 
0 | 
2 - end 
0 - start 
3 | 
0 | - 7 
4 | 
0 - end 
5 
0 
2 
. 
. 
. 

-|startend,都为可视化表示,我只需要它在列的列表:

6 
3 
7 
. 
. 
. 

我目前有一种方法,通过使用增量head -n $itail -n 5从列表中删除5行,然后我使用paste -sd+ - | bc将所有值相加。但是由于有10万列,所以这太慢了。

如果任何人有任何补充,我将不胜感激。让我知道是否需要更多信息。

谢谢

+0

'perl的-lne“$ T + = $ _;如果(没有$%5){打印$ T; $ t = 0;}'文件' –

+0

golf,eh @ k-five? 'awk'0 *(t + = $ 1)== NR%5 {print t; t = 0}'file' is 18 char short :-) –

回答

4

看起来awk是使用天然工具:

awk '{ sum += $1 } NR % 5 == 0 { print sum; sum = 0 }' 

在第1列添加值sum。如果记录编号5为0,则打印总和并将其重置为0.请注意,如果最后一组记录是短的(组中有1-4个元素),则它们的总和不会打印。如果您想要打印短组的总和,请将END { if (NR % 5 != 0) print sum }添加到脚本中。

由于这会使用单个命令对数据文件进行单次传递,因此很难击败它。使用Perl可能会更快一些。我不知道Python如何对付Awk或Perl。

+0

对于100k行花费了0.055s。 – Jack

+2

@Jack:不管您是否可以用其他语言打败它,这都不太可能相关。我想你可能已经从内核文件缓冲区缓存中的大部分文件中受益。但有时间数字是很好的。谢谢! –

3

您可以使用它的awk。 名为file1说文件包含

1 
0 
2 
3 
0 
0 
1 
0 
0 
2 
0 
3 
0 
4 
0 
5 
0 
. 
. 
. 

所以awk命令是这样:

awk 'begin{sum=0;} {sum=sum+1;if(NR%5==0){print sum;sum=0;}}' file1 
+1

在Awk中,变量会自动初始化为0(或空字符串),所以'begin'块(通常拼写为'BEGIN'大写)并不是真的需要。在每行代码中,您将“1”而不是“$ 1”添加到总和 - 您正在对行进行计数,而不是对这些行中的值进行求和。样本数据的输出(忽略三条线上有点)是三条线,表示'5​​'。 –