2014-03-30 161 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