2014-03-30 120 views
8

我想将大小为50GB的大文本文件拆分为多个文件。中的文件数据 像这 - [X =任何0-9之间的整数]将大文本文件(大约50GB)拆分为多个文件

xxx.xxx.xxx.xxx 
xxx.xxx.xxx.xxx 
xxx.xxx.xxx.xxx 
xxx.xxx.xxx.xxx 
............... 
............... 

可能有文件中的行的几十亿,我想例如30/40每秒百万文件写入。 我猜的步骤将是─

  • 我已经打开文件
  • 然后使用的ReadLine()必须按行读取文件行,同时写入新文件
  • 一旦它达到最大行数,它将创建另一个文件,并且 开始再次写入。

我在想,如何把所有这些步骤放在一个高效,快速的内存中。我已经看到了一些堆栈示例,但没有一个完全帮助我确切需要。如果有人能帮助我,我会很感激。

+5

在Python中如何做是比仅使用split更好的解决方案? –

+1

'readline()'不是你实际想要经常使用的函数 - Python文件本身就是懒惰的可迭代对象 - 只是用'for'循环遍历它。 –

+1

是的,你还没有显示出它需要在Python中完成的任何理由。使用Unix命令,或者[Windows上的Cygwin'split'](http://stackoverflow.com/questions/4128442/shell-command-to-split-large-file-into-10-smaller-files)。 – smci

回答

16

此工作解决方案使用shell中可用的split命令。由于作者已经接受了非python解决方案的可能性,请不要低估。

首先,我与

awk 'BEGIN{for (i = 0; i < 1000000000; i++) {print "123.123.123.123"} }' > t.txt 

然后我用split创建的测试文件与1000M条目(15 GB):

split --lines=30000000 --numeric-suffixes --suffix-length=2 t.txt t 

花5分钟以产生一组34个的小文件名字t00 - t33。 33个文件每个是458 MB,最后的t33是153 MB。

+0

我没有意识到unix中的分割命令。我非常欣赏这个解决方案。但对52GB文件使用分割命令需要很长时间。我想你的程序有助于使它更快。我不擅长awk命令。你能特别给我解释一下这个打印选项吗? @Andrey – saz

+0

@saz你有你自己的文件,所以你不需要运行awk。无论如何,这个脚本的意思是:'BEGIN {}'在读取输入文件之前在'{}'中执行语句(在这种情况下没有输入文件);该语句是一个'for'循环,其中唯一的语句是''print'text''(我使用“123 ...”,因为它与您的任务相似);最后'> t.txt'将awk输出重定向到't.txt'文件。详情请参阅man awk。花了5分钟来分割一个15GB的文件,所以我预计大约18分钟的52GB文件,但你的里程可能会有所不同。不要忘记检查可用磁盘空间,例如'df -h'。 – Andrey

+0

感谢您的解释。在我的情况下,花了很长时间。你的答案是我可以得到的最简单的解决方案之一。 Python程序可能并不复杂。现在我正在使用split命令。让我们看看我是否可以得到任何python解决方案。但再次感谢:) – saz

4

我会使用Unix公用程序拆分,如果它对您可用并且您唯一的任务是拆分文件。这里有一个但是纯Python的解决方案:

import contextlib 

file_large = 'large_file.txt' 
l = 30*10**6 # lines per split file 
with contextlib.ExitStack() as stack: 
    fd_in = stack.enter_context(open(file_large)) 
    for i, line in enumerate(fd_in): 
     if not i % l: 
      file_split = '{}.{}'.format(file_large, i//l) 
      fd_out = stack.enter_context(open(file_split, 'w')) 
     fd_out.write('{}\n'.format(line)) 

如果所有的线对他们4 3位数的号码,你有多个内核可用,那么你可以利用文件查找和运行多个进程。

+0

虽然你的解决方案很有趣,但问题被标记为python 2.7,所以'contextlib.ExitStack'将不起作用。 – jcollado

+0

对不起,我没有注意到python-2.7标签。 –

10
from itertools import chain, islice 

def chunks(iterable, n): 
    "chunks(ABCDE,2) => AB CD E" 
    iterable = iter(iterable) 
    while True: 
     # store one line in memory, 
     # chain it to an iterator on the rest of the chunk 
     yield chain([next(iterable)], islice(iterable, n-1)) 

l = 30*10**6 
file_large = 'large_file.txt' 
with open(file_large) as bigfile: 
    for i, lines in enumerate(chunks(bigfile, l)): 
     file_split = '{}.{}'.format(file_large, i) 
     with open(file_split, 'w') as f: 
      f.writelines(lines) 
+0

当被困在一个Windows机器上时,这个答案(具有较小的块大小)在大约7秒内将一个500 MB的文件分成7个独立的~75 MB文件。伟大的Python解决方案 - 谢谢! – kevinmicke