Eli*_*ley 9 sed awk shell-script text-processing
我有一个包含 8 列和几百万行的 CSV 文件(其中字段分隔符确实是逗号)。这是一个示例:
1000024447,38111220,201705,181359,0,12,1,3090
1064458324,38009543,201507,9,0,1,1,1298
1064458324,38009543,201508,9,0,2,1,90017
Run Code Online (Sandbox Code Playgroud)
打印给定列中所有数字的总和以及读取的行数的最快方法是什么?你能解释一下是什么让它更快吗?
ste*_*ver 16
$ datamash -t, count 3 sum 3 < file
3,604720
Run Code Online (Sandbox Code Playgroud)
一些测试
$ time gawk -F',' '{ sum += $3 } END{ print sum, NR }' longfile
604720000000 3000000
real 0m2.851s
user 0m2.784s
sys 0m0.068s
$ time mawk -F',' '{ sum += $3 } END{ print sum, NR }' longfile
6.0472e+11 3000000
real 0m0.967s
user 0m0.920s
sys 0m0.048s
$ time perl -F, -nle '$sum += $F[2] }{ print "$.,$sum"' longfile
3000000,604720000000
real 0m3.394s
user 0m3.364s
sys 0m0.036s
$ time { cut -d, -f3 <longfile |paste -s -d+ - |bc ; }
604720000000
real 0m1.679s
user 0m1.416s
sys 0m0.248s
$ time datamash -t, count 3 sum 3 < longfile
3000000,604720000000
real 0m0.815s
user 0m0.716s
sys 0m0.036s
Run Code Online (Sandbox Code Playgroud)
所以mawk
,datamash
似乎是一群人的选择。
Awk
是一种用于处理文本文件的快速且高性能的工具。
awk -F',' '{ sum += $3 }
END{ printf "Sum of 3rd field: %d. Total number of lines: %d\n", sum, NR }' file
Run Code Online (Sandbox Code Playgroud)
示例输出:
Sum of 3rd field: 604720. Total number of lines: 3
Run Code Online (Sandbox Code Playgroud)
概念说明:
我必须指出,所有这些非awk
替代方案只能在此类“理想”数字列上运行得更快。您只需要使用稍微复杂的格式(例如,在计算之前要删除一些附加信息<1064458324:a,<38009543:b,<201507:c,<9:d,<0:e,<1:f,<1:g,1298
)并且所有这些速度优势都将消失(更不用说其中一些将无法执行需要处理)。