Wie werden zwei Dateien und Ausgabezeilen verglichen, die nicht in der ersten erscheinen?

397
Zhro

Wenn ich eine Datei Amit einer Liste von Feldern habe:

2017-04-23 2017-04-30 2017-05-07 2017-05-14 2017-05-21 2017-05-28 2017-06-04 2017-06-11 2017-06-18 2017-06-25 

Und noch eine Datei Bmit einer Liste von Feldern:

2017-04-23 2017-04-30 2017-05-07 2017-05-14 2017-05-21 2017-05-28 2017-06-04 2017-06-11 2017-06-18 2017-06-25 2017-07-02 2017-07-09 2017-07-16 2017-07-23 

Wie kann ich diese beiden Dateien schnell unterscheiden, wo ich alle Felder in der Datei wissen möchte, Bdie nicht in der Datei vorhanden sind A?

Dies ist kein regulärer Unterschied, bei dem ich einen relativen Unterschied zwischen Dateien sehen möchte, sondern eher wie ein Hash-Vergleich, bei dem jede Zeile ein Eintrag in einer Map ist. Ich möchte eine Liste aller Zeilen in der Datei erhalten, Bdie nicht in der Datei vorhanden sind, Asodass ich sie entfernen kann, wobei jede Zeile in der Datei Aein Verzeichnis darstellt, das beibehalten werden soll.

Ich bin auf der Suche nach einer Bash / CoreUtils-Lösung.

4

3 Antworten auf die Frage

3
Gohu

Wenn Ihre Dateien sortiert sind, können Sie comm verwenden :

$ comm -13 A B 2017-07-02 2017-07-09 2017-07-16 2017-07-23 

mit Optionen:

  • -1: Unterdrückung der Spalte 1 (eindeutige Zeilen für FILE1)
  • -3: Spalte 3 unterdrücken (Zeilen, die in beiden Dateien erscheinen)
Wenn sie nicht sortiert sind, können Sie sie mit der Prozessersetzung `<(Dateiname sortieren)` sortieren Barmar vor 6 Jahren 1
2
Kamil Maciorowski

grep ist das richtige Werkzeug für den Job, obwohl es weder Bash noch von CoreUtils ist:

grep -Fxvf A B 

Alle diese Optionen sind POSIX-kompatibel. Von man 1 grep:

-f pattern_file

Lesen Sie ein oder mehrere Muster aus der mit dem Pfadnamen bezeichneten Datei pattern_file. Muster in pattern_filewerden durch a beendet. Ein Nullmuster kann durch eine leere Zeile in Musterdatei angegeben werden. Wenn nicht auch die Option -Eoder -Fangegeben ist, wird jedes Muster als BRE behandelt, wie im Volume Base Definitions von POSIX.1-2008, Abschnitt 9.3, Regelmäßige reguläre Ausdrücke, beschrieben.

-F

Verwenden Sie feste Zeichenfolgen. Behandeln Sie jedes angegebene Muster als String anstelle eines regulären Ausdrucks. Wenn eine Eingabezeile eines der Muster als zusammenhängende Folge von Bytes enthält, muss die Zeile übereinstimmen. Eine Nullzeichenfolge muss mit jeder Zeile übereinstimmen.

-v

Wählen Sie Linien aus, die mit keinem der angegebenen Muster übereinstimmen. Wenn die -vOption nicht angegeben ist, müssen die ausgewählten Zeilen diejenigen sein, die mit einem der angegebenen Muster übereinstimmen.

-x

Berücksichtigen Sie nur Eingabezeilen, die alle Zeichen in der Zeile verwenden, mit Ausnahme der Endung, um eine ganze feste Zeichenfolge oder einen regulären Ausdruck als übereinstimmende Zeilen zu finden.

1
Paulo

Ein anderer Weg mit einigen Pfeifen

cat A B|sort|uniq -u 

edit-UUOC

Es ist keine Katze nötig

sort A B|uniq -u 
Dies behandelt "A" und "B" gleichermaßen, während diese Dateien im ursprünglichen Problem nicht austauschbar sind. Was ist, wenn es eine Zeile in 'A' gibt, die nicht in 'B' steht? Kamil Maciorowski vor 6 Jahren 0
@Kamil Ja, du hast recht. Ich habe die Frage falsch verstanden, dies wird alle Zeilen drucken, die nicht in beiden Dateien vorhanden sind, was OP nicht will. Paulo vor 6 Jahren 0
Fix: `sortiere AAB | uniq -u`. :) Kamil Maciorowski vor 6 Jahren 1
Es klappt :) Aber es gibt ein anderes Problem mit meiner Lösung, die Ausgabe erscheint sortiert, vielleicht wäre dies ein Problem für den OP-Zweck. Paulo vor 6 Jahren 0
Haben Sie den letzten Absatz der Frage gelesen? Er möchte nur eine Liste von Verzeichnissen erhalten, die entfernt werden sollen. Das klingt nicht nach Ordnung. Auch scheinen seine Eingabedateien sortiert zu sein. Barmar vor 6 Jahren 0