2016-06-07 65 views
3

我有数百个文件要处理。每个文件都包含数百万行。大文件awk和sum rows

示例文件内容:

--------------- 
12 
3 
5 
--------------- 
8 
0 
5 
--------------- 
1 
5 
56 
4 
--------------- 

我需要(从以前的文件破折号分隔的数字之和),它看起来像下面的输出:

20 
13 
66 

我用whileifelse结合awk,但if/else大大减缓处理。

任何想法如何使用纯awk加快计算?

+0

你应该显示你的代码 - 在shell脚本或'awk'脚本中是'while'和'if'吗?无论如何,'awk'脚本中不需要循环或'if'条件。一个文件可以没有最后一行破折号? –

+1

wrt'我用while,if,else' - 读[为什么要使用shell循环处理文本被认为是坏行为](http://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice)和一个shell教程。另外请参阅Arnold Robbins编写的“有效的Awk编程”第4版。 –

+0

示例文件内容是否代表_single_或_multiple_文件? – mklement0

回答

3

你不需要的if/else块,

$ awk 'FNR>1 && /^----/ {print sum; sum=0; next} {sum+=$1}' file{1,2} 
20 
13 
66 
20 
13 
66 

例如您输入文件1和文件2的副本。也许你会一次运行一个或多个输入一个前缀的前缀,例如

$ awk 'FNR==1{block=0} FNR>1 && /^----/ {print FILENAME, ++block, sum; sum=0; next} 
             {sum+=$1}' file{1,2} 

file1 1 20 
file1 2 13 
file1 3 66 
file2 1 20 
file2 2 13 
file2 3 66 
+2

绝对是'抢救'时刻!祝你们好运。 – shellter

+1

对于这个问题,这些挑剔不是直接相关的,但对现实世界而言,它们可能是。如果最后一个文件不以破折号行结束,则不会输出最后一个和。这是一个麻烦解决。如果一个文件没有以破折号行结束,并且下一个文件没有以破折号行开始,那么可以合并这两个和。将第一行的破折线添加到“sum”似乎有点有趣 - 尽管“awk”将它视为零。但是对于格式良好的投入,这很好。 –

2

另一种方法。我很好奇它如何加快速度明智

awk -v RS='\n-+\n' -F'\n' 'NF {s=0; for(i=1; i<=NF; i++) s+=$i; print s}' file ... 
+1

由于多字符RS,您应该提及它是特定于gawk的。 –

3
$ awk '/^-+$/{if (s!="") print s; s=""; next} {s+=$0}' file 
20 
13 
66 

注释来""设定/比较,如果是VS只是初始化为空字符串为零的累计值不同的方式处理它吧。

-1

感谢大家花时间帮助我! awk的例子比起while/if条件来说非常快。感谢链接也描述了原因。看来我创建的代码中最糟糕的版本,我可以这样写: -/

我的代码版本,它的作品,以及,但它明显变慢:

sum=0 
while read line 
       do 
       if [ "$line" = "---------------" ]; then 
         echo $sum 
         sum=0 
       else sum=`echo $line $sum | awk '{print $1 + $2}'` 
       fi 
done < input_file.txt 

再次感谢大师!

+0

它不仅速度慢,而且会给出不同的输入值和/或环境设置和/或目录中的内容。不要在任何重要的事情上运行它。相反,选择你给予的解决方案之一,并做到这一点。你还问过任何想法如何使用纯awk来加速计算?所以有一个当之无愧的downvote发布你自己的解决方案,甚至没有做你所要求的! –