在Linux中洗牌文件行的最快方法
我想在Linux中洗牌一个包含数百万行字符串的大文件。我尝试了“sort-R”,但速度非常慢(一个16M大的文件需要50分钟)。有没有更快的实用程序可以替代它?根据您的描述,这50分钟并不是由实际的排序机制造成的。等待在Linux中洗牌文件行的最快方法,linux,bash,unix,Linux,Bash,Unix,我想在Linux中洗牌一个包含数百万行字符串的大文件。我尝试了“sort-R”,但速度非常慢(一个16M大的文件需要50分钟)。有没有更快的实用程序可以替代它?根据您的描述,这50分钟并不是由实际的排序机制造成的。等待/dev/random生成足够的熵可能会花费时间 一种方法是使用外部随机数据源(例如)以及一个变量。施瓦茨变换将要排序的数据转换为嵌入排序键的“丰富”数据。使用键对数据进行排序,然后丢弃键 要将此应用于您的问题,请执行以下操作: 生成一个随机数的文本文件,每行1行,行数与要排序的
/dev/random
生成足够的熵可能会花费时间
一种方法是使用外部随机数据源(例如)以及一个变量。施瓦茨变换将要排序的数据转换为嵌入排序键的“丰富”数据。使用键对数据进行排序,然后丢弃键
要将此应用于您的问题,请执行以下操作:
- 生成一个随机数的文本文件,每行1行,行数与要排序的文件相同。这可以在任何时候完成,在后台运行,在不同的服务器上运行,从random.org下载,等等。关键是在尝试排序时不会生成这种随机性
- 使用
粘贴
创建文件的增强版本:
paste random\u number\u file.txt string\u data.txt>tmp\u string\u data.txt
- 对该文件进行排序:
sort tmp\u string\u data.txt>sorted\u tmp\u string\u data.txt
- 删除随机数据:
cut-f2-sorted_tmp_string_data.txt>random_string_data.txt
这是基本思想。我试过了,它确实有效,但我没有1600万行文本或1600万行随机数。您可能希望将这些步骤中的一些通过管道传输,而不是全部保存到磁盘。使用
shuf
而不是sort-R
()
sort-R
的慢度为shuf
只是做一个随机排列,所以它没有那个问题
(这是在一篇评论中提出的,但由于某些原因,任何人都没有将其作为答案写下来)您可以尝试我的工具:。它能够在合理的时间内洗牌数百GB的文件
下面是有关洗牌实现的详细信息。它需要指定batchSize—写入输出时要保留在RAM中的行数。越多越好(除非您的RAM不足),因为总洗牌时间为(sourceFile中的行数)/batchSize*(完全读取sourceFile的时间)。请注意,程序洗牌整个文件,而不是每批洗牌一次
算法如下
- 我们将遍历源文件,读取所有行,并仅在内存中存储orderArray的第一个batchSize中的行。当我们得到所有这些行时,我们可以按要求的顺序将它们写入outFile,这是一个批量大小/行完成的工作
- 接下来,我们将一次又一次地重复整个过程,获取orderArray的下一部分,并从头到尾读取每个部分的源文件。最终整个orderArray都被处理了,我们就完成了
在我的机器(Core i5,16GB RAM,Win8.1,HDD东芝DT01ACA200 2TB,NTFS)上,我能够在大约5小时内使用350000的批大小洗牌132 GB(840000行)的文件。批量大小为2 000 000,大约需要8小时。阅读速度约为每秒118000行。Shuf?16MB文件有数百万行:您有非常短的行吗?顺便说一句:16MB不是很大。它将适合核心,我想排序将花费不到一秒钟的时间。@AndersLindahl:Shuf介绍的熵是什么?它是否像“sort-R”一样随机@wildplasser:哦……这是一个1600万行的文件,而不是16MB。这个文件的排序速度很快,但“sort-R”非常慢。@alpha\u cod:我猜它是
/dev/random
。您可以使用--random source
控制熵源。我怀疑这是问题所在:使用sort-R
(与使用shuf
的4秒相比),我在8分钟内获得了100%的cpu使用率。如果它在等待更多的熵,那么cpu的使用将是最小的,对吗?根据这个线程上的注释shuf
将所有内容加载到内存中,因此任何太大而无法加载到内存中的文件都将失败。这本身不是一个问题,但如果你试图用合法的大文件来实现这一点,这是一个问题。