有什么快速方法可以计算 4TB 文件中的行数?

有什么快速方法可以计算 4TB 文件中的行数?

我有一个从 Teradata 记录导出的 4TB 大文本文件,我想知道该文件中有多少条记录(= 在我的情况下为行)。

我怎样才能快速有效地做到这一点?

答案1

如果此信息尚未作为元数据存在于单独的文件中(或嵌入在数据中,或通过查询从中导出数据的系统可用),并且没有可用的某种描述的索引文件,则最快的方法来计算数量线是通过wc -l在文件上使用。

你确实无法做得更快。

来计算数量记录在文件中,您必须知道使用的记录分隔符并使用类似的方法awk来计算它们。同样,如果此信息尚未作为元数据存储在其他地方,并且如果无法通过对原始系统的查询获得该信息,并且如果记录本身尚未在文件中枚举和排序。

答案2

所以这里是awk和wc之间的速度测试

67G测试.tsv

time awk 'END {print NR}' test.tsv; time wc -l test.tsv

809162924

real    2m22.713s 
user    1m46.712s 
sys     0m19.618s 

809162924 test.tsv

real    0m20.222s 
user    0m9.629s 
sys     0m10.592s

另一个文件72G Sample.sam

time awk 'END {print NR}' Sample.sam; time wc -l Sample.sam
180824516

real    1m18.022s
user    1m5.775s
sys     0m12.238s

180824516 Sample.sam

real    0m22.534s
user    0m4.599s
sys     0m17.921s

答案3

您不应使用基于行的实用程序,例如awksed。这些实用程序将为read()输入文件中的每一行发出系统调用(请参阅回答为什么会这样)。如果你有很多行,这将是一个巨大的性能损失。

由于你的文件大小为 4TB,我猜有很多行。因此,甚至wc -l会产生大量read()系统调用,因为它16384每次调用仅读取字节(在我的系统上)。无论如何,这将是对awk和 的改进sed。最好的方法 - 除非你编写自己的程序 - 可能就是

cat file | wc -l

这对 cat 来说并不是无用的,因为每次系统调用都会cat读取字节块(在我的系统上),并且会发出更多字节,但不是直接在文件上,而是在管道上。但是,每次系统调用都会尝试尽可能多地读取数据。131072read()wc -lcat

答案4

我还对大型 VCF 文本文件进行了速度比较。这是我发现的:

216GB VCF 文本文件(在单个 SSD 上)

$ time wc -l <my_big_file>
16695620 

real    1m26.912s
user    0m2.896s
sys     1m23.002s
$ tail -5 <my_big_file>
$ time fgrep -n <last_line_pattern>  <my_big_file>
16695620:<last_line_pattern>

real    2m10.154s
user    0m46.938s
sys     1m22.492s
$ tail -5 <my_big_file>
$ LC_ALL=C && time fgrep -n <last_line_pattern>  <my_big_file>
16695620:<last_line_pattern>

real    1m38.153s
user    0m45.863s
sys     0m51.944s

最后:

$ time awk 'END {print NR}' <my_big_file>
16695620

real    1m44.074s
user    1m11.275s
sys     0m32.780s

结论一:

  • wc -lSSD 似乎最快。

216GB VCF 文本文件(在具有 8 个 HDD 的 RAID10 设置上)

$ time wc -l <my_big_file>
16695620 

real    7m22.397s
user    0m10.562s
sys 4m1.888s
$ tail -5 <my_big_file>
$ time fgrep -n <last_line_pattern>  <my_big_file>
16695620:<last_line_pattern>

real    7m7.812s
user    1m58.242s
sys 3m12.355s
$ tail -5 <my_big_file>
$ LC_ALL=C && time fgrep -n <last_line_pattern>  <my_big_file>
16695620:<last_line_pattern>

real    4m34.522s
user    1m26.764s
sys 1m58.247s

最后:

$ time awk 'END {print NR}' <my_big_file>
16695620

real    6m50.240s
user    2m37.574s
sys 2m43.498s

结论2:

  • wc -l看起来与其他人相当。
  • 较低的时间LC_ALL=C && time fgrep -n <last_line_pattern>很可能是由于缓存造成的,因为后续wc -l也显示了较低的时间。

相关内容