2013-10-20 94 views
2

所以我有一個問題。我正在處理由4行多行組成的.txt文件。我正在python 3中工作。處理速度 - 編輯大型2GB文本文件python

我寫了一個代碼,意思是取一個文本文件的第二行和第四行,只保留這兩行的前20個字符(同時保留第一行和第三行未經編輯) ,並創建一個新的編輯文件,包括編輯後的第2行和第4行以及未編輯的第1行和第3行。這種趨勢對每一行都是一樣的,因爲我使用的所有文本文件的行號都是4的倍數。

這適用於小文件(共約100行),但我需要的版本是50百萬+線,它需要4個多小時。

以下是我的代碼。任何人都可以給我一個關於如何加快我的程序的建議嗎?謝謝!

import io 
import os 
import sys 

newData = "" 
i=0 
run=0 
j=0 
k=1 
m=2 
n=3 
seqFile = open('temp100.txt', 'r') 
seqData = seqFile.readlines() 
while i < 14371315: 
    sLine1 = seqData[j] 
    editLine2 = seqData[k] 
    sLine3 = seqData[m] 
    editLine4 = seqData[n] 
    tempLine1 = editLine2[0:20] 
    tempLine2 = editLine4[0:20] 
    newLine1 = editLine2.replace(editLine2, tempLine1) 
    newLine2 = editLine4.replace(editLine4, tempLine2) 
    newData = newData + sLine1 + newLine1 + '\n' + sLine3 + newLine2 
    if len(seqData[k]) > 20: 
     newData += '\n' 
    i=i+1 
    run=run+1 
    j=j+4 
    k=k+4 
    m=m+4 
    n=n+4 
    print(run) 

seqFile.close() 

new = open("new_100temp.txt", "w") 
sys.stdout = new 
print(newData) 
+0

你使用什麼環境? –

+5

你真的需要python嗎? 'awk'NR%2 == 0 {$ 0 = substr($ 0,1,20)} 1'old.txt> new.txt'? – Kevin

+0

@ZagorulkinDmitry我使用PyDev(Eclipse) –

回答

2

這可能更快,如果你只是讀4行的時間和處理這些(未經測試):

with open('100temp.txt') as in_file, open('new_100temp.txt', 'w') as out_file: 
    for line1, line2, line3, line4 in grouper(in_file, 4): 
     # modify 4 lines 
     out_file.writelines([line1, line2, line3, line4]) 

哪裏grouper(it, n)是一次產生iterabel itn項的函數。它作爲itertools模塊的examples之一給出(也可參見SO上的this anwer)。以這種方式迭代文件類似於在文件上調用readlines(),然後手動迭代結果列表,但它每次只讀取幾行內存。

+0

如果這是最好的答案,您應該使用'with'而不是手動打開和關閉文件。 – kevinsa5

+0

感謝您的建議,與'與'的解決方案確實更清潔。 –

2

您正在處理內存中的兩個文件(輸入和輸出)。如果文件很大(分頁),它可能會導致時間問題。嘗試(僞)

Open input file for read 
Open output file for write 
Initialize counter to 1 
While not EOF in input file 
    Read input line 
    If counter is odd 
     Write line to output file 
    Else 
     Write 20 first characters of line to output file 
    Increment counter 
Close files 
2

最大的問題在這裏似乎是一次讀取整個文件:

seqData = seqFile.readlines()

相反,你應該打開你的源文件和輸出文件在第一。然後遍歷第一個文件,操縱線,如你所願:

outfile = open('output.txt', 'w') 
infile = open('input.txt', 'r') 

i = 0 
for line in infile: 
    if i % 2 == 0: 
     newline = line 
    else: 
     newline = line[:20] 

    outfile.write(newline) 
    i += 1 

outfile.close() 
infile.close() 
1

請參閱docs以瞭解讀取文件的最佳方式。與其將所有內容保存在內存中,這與seqData = seqFile.readlines()所做的相同,只是迭代而已。 Python負責緩衝等。對你來說,它是快速和高效的。另外,您不應該自己打開和關閉文件(如其他答案) - 使用with關鍵字。

lineCount = 0 
with open("new_100temp.txt", "w") as newFile, open("100temp.txt","r") as oldFile: 
    for line in oldFile: 
     #start on line 1, keep 1st and 3rd as is, modify 2nd and 4th 
     lineCount += 1 
     if lineCount%4 == 1 or lineCount%4 == 3: 
      newFile.write(line) 
     else: 
      newFile.write(line[:20] + "\n") 
      # printing is really slow, so only do it every 100th iteration: 
     if lineCount % 100 == 0: 
      print lineCount 

我剛剛試了一百萬行垃圾文本,並在不到一秒的時間內完成了它。正如Kevin所說,像這樣簡單的文本工作對shell來說是很好的處理。