我有一个大的文本文件,大约8 GB,我的行需要随机和均匀地随机播放。我无法对文本文件进行分区和随机播放 - 必须在整个文件上进行随机播放。
我遇到了GNU shuf
在资源有限的主机(1 GB内存)上崩溃的限制,所以我正在探索故意留在这个主机能力范围内的替代方案。
我有一个想法是从[1..n]
构建一个Python(2.7.5)数字列表,其中n
是这个8 GB文件中的行数 - 大约2500万行 - 随机置换列表,并遍历列表以获取要提供给sed -n <line_index>p
的索引(或行号)。
Python是否有能力置换25M元素列表? sed
是否有能力通过索引有效地提取线,其中指数是该范围的?
是否有更有效的方法在资源受限的主机上重排大型文本文件?
答案 0 :(得分:3)
我认为以下内容可能有用。
from random import shuffle
# ... rest of the code ...
lnPos = [f.tell()]
for l in f.readlines(): lnPos.append( f.tell() )
shuffle( lnPos )
# Now open a file to write and write the lines
for pos in lnPos:
f.seek(pos, 0)
fOut.write( f.readline() )
我没有检查过语法错误,但我认为这可能会起作用。让我知道事情的后续。 :)
答案 1 :(得分:0)
这可能适合你(GNU sed&amp; sort):
seq $(cat file | wc -l) | sort -R | sed 's|.*|sed -n '\''&{p;q}'\'' file|e' >output
答案 2 :(得分:0)
当您遍历文件行时,可以将它们随机写入16个分区之一。然后,随机播放每个分区,然后重新加入它们。
一些(未经测试的)代码。该函数采用类似文件的对象in_file和out_file,以及要使用的分区数。
def shuffle(in_file, out_file, n):
out = [open('shard-%02d-of-%02d' % (i, n), 'w') for i in xrange(n)]
for line in infile:
out[random.randrange(n)].write(line)
for o in out: o.close()
for i in xrange(n):
with open('shard-%02d-of-%02d' % (i, n), 'r') as part:
lines = part.readlines()
random.shuffle(lines)
for x in lines:
out_file.write(x)