Zwei große Textdateien unterscheiden

32

Ich habe zwei große Dateien (jeweils 6 GB). Sie sind unsortiert, mit Zeilenvorschüben ( \n) als Trennzeichen. Wie kann ich sie unterscheiden? Es sollte unter 24 Stunden dauern.

jonasl
quelle

Antworten:

45

Die naheliegendste Antwort ist die Verwendung des Befehls diff. Es ist wahrscheinlich eine gute Idee, den Parameter --speed-large-files hinzuzufügen.

diff --speed-large-files a.file b.file

Sie erwähnen unsortierte Dateien, daher müssen Sie die Dateien möglicherweise zuerst sortieren

sort a.file > a.file.sorted
sort b.file > b.file.sorted
diff --speed-large-files a.file.sorted b.file.sorted

Sie können das Erstellen einer zusätzlichen Ausgabedatei sparen, indem Sie die Ausgabe der zweiten Sortierung direkt in diff leiten

sort a.file > a.file.sorted
sort b.file | diff --speed-large-files a.file.sorted -

Offensichtlich laufen diese am besten auf einem System mit viel verfügbarem Speicher und Sie werden wahrscheinlich auch viel freien Speicherplatz benötigen.

Aus Ihrer Frage ging nicht hervor, ob Sie diese bereits ausprobiert haben. Wenn ja, wäre es hilfreich zu wissen, was schief gelaufen ist (zu lange usw. gedauert hat). Ich habe immer festgestellt, dass die Befehle stock sort und diff mindestens genauso gut funktionieren wie benutzerdefinierte Befehle, es sei denn, es gibt einige sehr domänenspezifische Eigenschaften der Dateien, die es ermöglichen, Dinge anders zu machen.

Richm
quelle
2
+1. Sie können alle temporären Dateien mit Named Pipes weglassen. Verwenden Sie mkfifozu erstellen , [ab].file.sortedbevor sie als Ausgabe verwendet sort. Stellen Sie beide sorts mit &in den Hintergrund und verwenden Sie beide als Dateinamen für diff.
krissi
15
@krissi Sie können den gleichen Effekt auch mit dieser Syntax erzielen:diff <(command 1) <(command 2)
Michael Mrozek
Danke hat funktioniert. Ich brauchte ein paar GB Speicher gedacht, aber eine 16 GB Amazon EC2-Instanz
reparierte
7
Wenn sich jemand wie ich fragt, warum <(cmd1) <(cmd2)Syntax funktioniert (da es sich anhört, als würde man die Standardeingabe zweimal umleiten!), Versuchen Sie es echo hello <(cmd1) <(cmd2). Du wirst so etwas sehen, hello /dev/fd/63 /dev/fd/62was es plötzlich klar macht;)
alex
3
Nach meiner Erfahrung --speed-large-fileshilft die Option nicht, wenn Sie nicht über genügend RAM verfügen. Die Vorsortierung ist auch nicht hilfreich, wenn Sie eine mehrzeilige Datensatzstruktur haben, die Sie beibehalten möchten. Die oben genannten Optionen (von @unhammer) sind interessant, aber die Ausgabe von rdiffund bsdiffist eher binär. Die Installation bdiffvon der Heirloom Toolbox aus scheint eine schwierige Aufgabe zu sein (erfordert Heirloom-Devtools, ausgestorbene Header-Dateien usw.). Lohnt sich der Aufwand wirklich? Gibt es noch andere Alternativen?
Christian Pietsch
5

Wenn diffSie die Eingaben sortieren und dem Programm mitteilen , dass die Eingaben sortiert sind, würde dies zu einer enormen Beschleunigung führen. Ich kenne keine diffmit einer solchen Option, gehe aber commvon sortierten Eingaben aus und werde viel schneller sein, wenn sie für Ihre Zwecke ausreichen.

Karl
quelle
commhat großartig funktioniert, noch nie davon gehört, aber anscheinend ist es in coreutils.
theferrit32