2017-05-05 59 views
2

我需要處理幾個非常大的文件(每個大於90GB)。只有一小部分文件對我很重要。我想掃描文件並將必要的行寫入另一個文件,所以我不需要每次運行實驗時都處理這些大文件。每行大約有1000個字符。python - 處理非常大的文件(> 90GB)

我使用下面的代碼:

def readFile(inputFile, outputFile): 
    startDate = datetime.datetime.strptime('10/06/2010 00:00:00', '%m/%d/%Y %H:%M:%S') 
    endDate = datetime.datetime.strptime('10/13/2010 23:59:59', '%m/%d/%Y %H:%M:%S') 

    total_lines = 0 

    with open(inputFile, 'r') as a_file: 
     for a_line in a_file: 

      total_lines += 1 

      id, date, content = splitLine(a_line) 

      datetime_object = datetime.datetime.strptime(date, '%m/%d/%Y %H:%M:%S') 

      if (datetime_object > startDate and datetime_object < endDate): 
       appendToFile(outputFile, a_line) 

    return total_lines 

def splitLine(long_string): 
    values = long_string.split(",") 
    return values[0],values[1],values[2] 

def appendToFile(outputFile, outputString): 
    try: 
     file = open(outputFile, 'a+') 
     file.write(outputString) 
     file.close() 
    except Exception as ex: 
     print("Error writing to file: " + outputFile) 
    return 

的問題是,我每次運行該腳本時,該過程被卡住各地10.000.000th線。當我使用htop命令時,我可以看到Python在卡住時僅使用大約8GB的RAM,並且使用的虛擬內存不斷增加,然後OS在一段時間後終止該進程。

我使用了不同的文件,以及Python 2.7和3.5。我也嘗試使用with open(inputFile, 'r', 16777216)來使用緩衝,但結果沒有改變。我在macOS Sierra 10.12.4上運行代碼,機器有16GB的RAM。

任何想法?

+0

'appendToFile()'做了什麼?你應該包括一個完整的例子,其中包括*所有代碼需要重現問題(「[mcve]」)。 – Carpetsmoker

+0

不要在評論中發佈你的代碼,你可以[編輯]你的問題;-) – Carpetsmoker

+0

@Carpetsmoker編輯:) – gokhan

回答

0

打開文件,直到找到你想要的東西。像這樣:

f = open('yourfile') 

piece = f.read(4096) 
while piece: 
    # Implementation for each piece 
    piece = f.read(4096) 
f.close() 
0

更有效的方法是從python調用Unix awk命令。這將適用於Mac和Unix。

你打電話叫蟒蛇Unix命令是這樣的:

import os 
os.popen('ls -l > result.txt') 

運行此示例代碼將創建一個名爲的Result.txt文件,其中包含ls -l命令的輸出。

同樣,您可以使用awk掃描您的文件並將結果傳輸到另一個文件。

從AWK的手冊頁:

AWK

NAME AWK - 圖案定向掃描和處理語言

概要

awk [ -F fs ] [ -v var=value ] [ 'prog' | -f progfile ] [ file ... ] 

說明:

Awk掃描每個輸入文件的行,這些行與在prog中或在指定爲-f progfile的一個或多個文件中指定的任何一組模式匹配。對於每個模式,可以有一個相關的動作,當一行文件與該模式匹配時將執行相關的動作。每行匹配 針對每個模式動作語句的模式部分;針對每個匹配的模式執行相關聯的動作。文件名稱 - 表示標準輸入。任何形式爲var = value的文件都被視爲一個賦值,而不是文件名,並且如果它是一個文件名,它將在它打開的時候被執行。選項-v後跟var = value是在執行prog之前完成的任務;任何數量的-v選項都可能存在。 -F fs選項將輸入字段分隔符定義爲正則表達式fs。

閱讀此答案https://unix.stackexchange.com/questions/76805/read-log-file-between-two-dates瞭解如何使用awk在兩個日期之間讀取日誌文件。