大文件的 awk 和 sum 行

Posted

技术标签:

【中文标题】大文件的 awk 和 sum 行【英文标题】:awk and sum rows for large files 【发布时间】:2016-10-08 01:14:58 【问题描述】:

我有数百个文件要处理。每个文件包含数百万行。

示例文件内容:

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

我需要得到如下所示的输出(由前一个文件中的破折号分隔的数字总和):

20
13
66

我将whileifelseawk 结合使用,但if/else 大大减慢了处理速度。

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

【问题讨论】:

你应该展示你的代码——whileif是在shell脚本中还是在awk脚本中?无论如何,awk 脚本中不需要循环或if 条件。如果没有最后一行破折号,文件会结束吗? wrt I used while, if, else - 阅读 why-is-using-a-shell-loop-to-process-text-considered-bad-practice 和一个 shell 教程。还可以获取 Arnold Robbins 的《Effective Awk Programming, 4th Edition》一书。 样本文件内容是代表单个还是多个文件? 【参考方案1】:

你不需要 if/else 块,

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

例如对于您的输入文件 1 和文件 2 的副本。例如,您可能会一次运行一个或多个输入的总和前加上前缀

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

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

【讨论】:

绝对是awk to the rescue 时刻!祝大家好运。 对于这个问题,这些挑剔的东西并不直接相关,但对于现实世界,它们可能是。如果最后一个文件不以破折号行结尾,那么您将不会输出最后一个总和。解决这个问题很麻烦。如果一个文件不是以一行破折号结尾,而下一个文件不是以一行破折号开头,那么您将合并这两个总和。将第一行的破折号行添加到sum 似乎有点有趣——尽管awk 将其视为零已经足够好了。但是对于格式良好的输入,这很好。【参考方案2】:
$ awk '/^-+$/if (s!="") print s; s=""; next s+=$0' file
20
13
66

请注意 s 与 "" 的设置/比较,以区别处理它,如果其总和值为 0 与刚刚初始化为空字符串。

【讨论】:

【参考方案3】:

另一种选择。我很好奇它是如何在速度方面叠加的

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

【讨论】:

由于多字符 RS,您应该提到它是 gawk 特定的。【参考方案4】:

感谢大家花时间帮助我!与 while/if 条件相比,您的 awk 示例速度非常快。感谢您的链接也描述了原因。看来我创建了我能写的最糟糕的代码版本:-/

我的代码版本也可以,但速度非常慢:

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

再次感谢大师!

【讨论】:

不仅速度很慢,而且在给定各种输入值和/或环境设置和/或运行它的目录的内容的情况下,它会破坏您的输出。不要在任何重要的事情上运行它。而是选择您获得的解决方案之一并执行此操作。你还问了Any ideas how to use pure awk to speed up calculations?,所以你应该投反对票,因为你发布了你自己的解决方案,甚至没有按照你的要求做!

以上是关于大文件的 awk 和 sum 行的主要内容,如果未能解决你的问题,请参考以下文章

awk用法

windows命令行大汇总

sed 或 awk 将两个文件与 sum 组合

windows命令行大汇总

windows命令行大汇总

LINUX awk 语句 awk ' SUM += $1 END print SUM '请问这个要怎么理解,需详细