2017-05-05 3 views
2

Ich muss ein paar sehr große Dateien (> 90GB) verarbeiten. Nur ein kleiner Teil der Dateien ist wichtig für mich. Ich möchte die Dateien durchsuchen und die erforderlichen Zeilen in eine andere Datei schreiben. Daher muss ich nicht jedes Mal, wenn ich ein Experiment durchführe, so große Dateien verarbeiten. Jede Zeile hat ungefähr 1000 Zeichen.Python - Verarbeitung sehr großer Dateien (> 90GB)

Ich verwende den folgenden Code ein:

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 

Das Problem ist, jedes Mal wenn ich das Skript ausführen, wird der Prozess um 10.000.000th Linie fest. Wenn ich den Befehl htop benutze, kann ich sehen, dass Python nur etwa 8 GB RAM verwendet, wenn es steckenbleibt, und der verwendete virtuelle Speicher nimmt zu und das Betriebssystem tötet den Prozess nach einer Weile.

Ich habe verschiedene Dateien verwendet, und auch beide Python 2.7 und 3.5. Ich versuchte auch, with open(inputFile, 'r', 16777216) zu verwenden, Pufferung zu verwenden, aber das Ergebnis änderte sich nicht. Ich benutze den Code auf macOS Sierra 10.12.4 und der Rechner hat 16 GB RAM.

Irgendwelche Ideen?

+0

Was bewirkt 'appendToFile()'? Sie sollten ein vollständiges Beispiel angeben, das * all * enthält, das der Code benötigt, um das Problem zu reproduzieren ("[mcve]"). – Carpetsmoker

+0

Poste deinen Code nicht in Kommentaren, du kannst deine Frage bearbeiten ;-) – Carpetsmoker

+0

@Carpetsmoker bearbeitet :) – gokhan

Antwort

0

Öffnen Sie die Datei in Stücke, bis Sie finden, was Sie wollen. Wie folgt:

f = open('yourfile') 

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

Eine effizientere Möglichkeit wäre, Unix awk Befehl von Python aufzurufen. Dies funktioniert sowohl auf Mac als auch auf Unix.

rufen Sie rufen Unix von Python wie diese Befehle:

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

diesen Beispielcode ausführen, wird eine Datei namens result.txt erstellen, die die Ausgabe des Befehls ls -l enthält.

In ähnlicher Weise können Sie Ihre Dateien mit awk durchsuchen und das Ergebnis in eine andere Datei leiten.

Von der Handbuchseite von awk:

awk

BEZEICHNUNG awk - Muster-directed Abtast- und Verarbeitungssprache

SYNOPSE

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

DESCRIPTION:

Awk scannt jede Eingabedatei nach Zeilen, die mit einem Satz von Mustern übereinstimmen, die in prog oder in einer oder mehreren Dateien mit der Bezeichnung -f progfile angegeben sind. Mit jedem Muster kann eine verknüpfte Aktion ausgeführt werden, die ausgeführt wird, wenn eine Zeile einer Datei mit dem Muster übereinstimmt. Jede Zeile entspricht mit dem Musterteil jeder Musteraktionsanweisung; Die zugehörige Aktion wird für jedes übereinstimmende Muster ausgeführt. Der Dateiname - bedeutet die Standardeingabe. Jede Datei der Form var = value wird als Zuweisung und nicht als Dateiname behandelt und wird zu dem Zeitpunkt ausgeführt, an dem sie geöffnet würde, wenn es sich um einen Dateinamen handelt. Die Option -v gefolgt von var = value ist eine Zuweisung, die ausgeführt werden muss, bevor prog ausgeführt wird. Eine beliebige Anzahl von -v Optionen kann vorhanden sein. Die Option -Fs definiert das Eingabefeldtrennzeichen als regulären Ausdruck fs.

Lesen Sie diese Antwort https://unix.stackexchange.com/questions/76805/read-log-file-between-two-dates, um zu sehen, wie Sie mit awk Protokolldateien zwischen zwei Daten lesen können.

Verwandte Themen