Große Datenverarbeitung: Entfernen von Zeilen in einem Textdokument in einem anderen Dokument

472
AndrewWilliams

Ich habe 2 große Textdateien (~ 500M, ~ 15GB), die wie folgt aussehen:

FileP.txt:

test@test.com: testtest test@test.com1: testtest1 test@test.com2: testtest2 test@test.com3: testtest3 test@test.com4: testtest4

FileE.txt

test@test.com:testtest test@test.com0:testtest0 test@test.com2:testtest2 test@test.com3:testtest3 test@test.com5:testtest5 

(Beachten Sie, wie FileE.txtsich Zeilen befinden, die nicht in sind FileP.txt. Ich möchte nicht, dass diese enthalten sind. Fettdrucken sind Zeilen, die in enden sollten output.txt, da sie nicht in sind FileE.txt.)

Ich will laufen FileE.txtgegen FileP.txtund entfernen Sie alle Zeilen, die in gefunden wurden FileE.txtaus FileP.txtund Ausgabe in eine neue Datei.

Es sollte so aussehen:

Ausgabe.txt:

test@test.com1: testtest1 test@test.com4: testtest4

Ich habe ein paar Befehle ausprobiert,

Hier ist mein grep-Befehl:

$ grep -Fvxf FileE.txt FileP.txt > output.txt 

Ich erhalte jedoch diese Fehlermeldung (Offensichtlich, weil die Dateien zu groß sind):

grep: memory exhausted 

Für interessierte, laufende $ ulimit -aErgebnisse:

core file size (blocks, -c) unlimited data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited open files (-n) 256 pipe size (512 bytes, -p) 8 stack size (kbytes, -s) 2032 cpu time (seconds, -t) unlimited max user processes (-u) 256 virtual memory (kbytes, -v) unlimited 

Meine Frage ist also: Was wäre der effizienteste und einfachste Weg, um diesen Prozess abzuschließen?

HINWEIS: Dateien werden nicht sortiert.

1
Werden die Dateien garantiert sortiert? Bitte antworten Sie nicht in Kommentaren. Bearbeiten Sie Ihre Frage, um sie klarer und vollständiger zu machen. Scott vor 6 Jahren 0
Sortieren Sie die Dateien, führen Sie eine `diff FileP.txt File.txt` durch und behalten Sie nur die Zeilen mit dem vorangestellten` <`? xenoid vor 6 Jahren 1
@Scott Done. Wie würde ich Zeilen nur mit vorangestellt halten AndrewWilliams vor 6 Jahren 0
Eine andere Idee? Bringe sie in eine MySQL-Datenbank. Bei so großen Daten ist eine reine Textdatei niemals eine gute Option. Auch wenn diese MySQL-Datenbank nur als riesiger Cache angesehen wird. Das heißt, wenn Sie in der Kommandozeilenwelt bleiben müssen, spüre ich Ihren Schmerz. JakeGould vor 6 Jahren 0
@ JakeGould: Ich habe ehrlich darüber nachgedacht. Ich muss in CL bleiben :( AndrewWilliams vor 6 Jahren 0

2 Antworten auf die Frage

0
Scott

Wenn die Dateien sortiert sind, tun Sie dies

comm -23 fileP.txt fileE.txt 

commvergleicht zwei sortierte Dateien und sucht nach Zeilen, die sie gemeinsam haben. Angenommen, diese Datei mit Farben, deren Namen mit Konsonanten beginnen:

blue green purple red white yellow 

und diese Liste von Farben, deren Namen mit Vokalen enden:

blue indigo orange purple white 

Der Befehl comm colors1 colors2erzeugt diese Ausgabe:

 blue green indigo orange purple red white yellow 

Dabei gilt:
Die erste Spalte enthält Farben, die mit Konsonanten beginnen und enden (in, colors1jedoch nicht colors2), die zweite Spalte enthält Farben, die mit Vokalen beginnen und enden (in, colors2jedoch nicht colors1), und die dritte Spalte enthält Farben, die mit Konsonanten beginnen und mit Vokalen enden (in beiden colors1und colors2). Für Ihre Dateien (in Ihrer Frage gezeigt) wird comm fileP.txt fileE.txtproduziert

 test@test.com:testtest test@test.com0:testtest0 test@test.com1:testtest1 test@test.com2:testtest2 test@test.com3:testtest3 test@test.com4:testtest4 test@test.com5:testtest5 

Die Optionen sind etwas nicht intuitiv: -23bedeutet, die zweite und dritte Spalte zu unterdrücken, wobei nur die erste angezeigt wird (Zeilen, die sich in der ersten Datei befinden, nicht aber in der zweiten). So,

$ comm -23 fileP.txt fileE.txt test@test.com1:testtest1 test@test.com4:testtest4 

Beachten Sie, dass dies nicht richtig funktioniert, wenn die Dateien nicht sortiert werden. Wenn die Dateien nicht sortiert sind, sortieren Sie sie.

0
Scott

Um einen Kommentar mit xenoid zu vergrößern, sortieren Sie die Dateien und geben Sie den Typ ein

diff fileP.txt fileE.txt | sed -n 's/^< //p' 

Die Ausgabe von diffzeigt die Zeilen, die nur in der ersten Datei enthalten sind , und die Zeilen, die sich nur in der zweiten Datei befinden, und die vorangestellt ist . Das sedselektiert nur die Zeilen, die mit beginnen, und entfernt es.