bash - 将一个太大而无法容纳在内存中的文件洗牌

Geo*_*rge 9 bash

我有一个太大而无法放入内存的文件.shuf似乎在RAM中运行,并且sort -R不会随机播放(相同的行最终彼此相邻;我需要对所有行进行洗牌).除了推出自己的解决方案之外还有其他选择吗?

daw*_*awg 9

使用decorate-sort-undecorate模式的形式,awk您可以执行以下操作:

$ seq 10 | awk 'BEGIN{srand();} {printf "%06d %s\n", rand()*1000000, $0;}' | sort -n | cut -c8-
8
5
1
9
6
3
7
2
10
4
Run Code Online (Sandbox Code Playgroud)

对于文件,您可以:

$ awk 'BEGIN{srand();} {printf "%06d %s\n", rand()*1000000, $0;}' SORTED.TXT | sort -n | cut -c8- > SHUFFLED.TXT
Run Code Online (Sandbox Code Playgroud)

cat管道开头的文件.

这是通过生成一个随机数列000000999999包含(装饰); 对该列进行排序(排序); 然后删除列(undecorate).这应该适用于sort不能理解数字的平台,方法是生成一个带有前导零的列用于词典排序.

如果需要,您可以通过以下几种方式增加随机化:

  1. 如果您的平台sort理解数值(POSIX,GNU和BSD),您可以awk 'BEGIN{srand();} {printf "%0.15f\t%s\n", rand(), $0;}' FILE.TXT | sort -n | cut -f 2-使用近双浮点进行随机表示.

  2. 如果仅限于词典排序,只需将两个调用组合rand成一列,如下所示:awk 'BEGIN{srand();} {printf "%06d%06d\t%s\n", rand()*1000000,rand()*1000000, $0;}' FILE.TXT | sort -n | cut -f 2-它给出了12位随机化的复合数.


Leo*_*all 5

计算行数 ( wc -l) 并以随机顺序生成与行号相对应的数字列表 - 可能通过在临时文件中生成数字列表(使用/tmp/,通常位于 RAM 中,因此相对较快)。然后将每个数字对应的行按照打乱数字的顺序复制到目标文件中。

由于在文件中查找换行符的量很大,这会导致时间效率低下,但它几乎适用于任何大小的文件。