Gemeinsame Zeilen (Ähnlichkeiten) von zwei Textdateien ausgeben (das Gegenteil von diff)?

20

Diff ist ein großartiges Tool, um die Änderungen zwischen zwei Dateien anzuzeigen. Aber wie lassen sich die Ähnlichkeiten zweier Textdateien anzeigen (ohne Berücksichtigung der Unterschiede)?

Dh Beispiel Input:

a:
Foo Bar
X
Hello
World
42

b:
Foo Baz
Hello
World
23

Pseudo-Ausgabe (so ähnlich):

@@ 2,3
=Hello World

Es reicht nicht aus, beide Dateien zu sortieren und comm zu verwenden, da in diesem Fall die Zeileninformationen verloren gehen.

maxschlepzig
quelle

Antworten:

24

Wie wäre es mit diff, obwohl Sie kein diff wollen? Versuche dies:

diff --unchanged-group-format='@@ %dn,%df 
  %<' --old-group-format='' --new-group-format='' \
  --changed-group-format='' a.txt b.txt

Folgendes erhalte ich mit Ihren Beispieldaten:

$ cat a.txt 
Foo Bar
X
Hello
World
42
$ cat b.txt 
Foo Baz
Hello
World
23
$ diff --unchanged-group-format='@@ %dn,%df
%<' --old-group-format='' --new-group-format='' \
  --changed-group-format='' a.txt b.txt
@@ 2,3
Hello
World
Mike Gray
quelle
2
Sie können das Einbetten einer wörtlichen Newline wie folgt vermeiden:...%df'$'\n''%<'...
Bis auf weiteres angehalten.
1
Sie können dies auch folgendermaßen tun: ... --unchanged-group-format="@@ %dn,%df%c'\012'%<" ...(Beachten Sie die doppelten Anführungszeichen.)
Bis auf weiteres angehalten.
Tolles Zeug! Ich kannte diese Optionen nicht, weil ich mir gerade die Manpage für
Unterschiede angesehen habe
Ich verwende diff --version diff (GNU diffutils) 2.8.1 Und ich erhalte den folgenden Fehler: diff: widersprüchliche Ausgabeoptionen diff: Versuchen Sie diff --help für weitere Informationen.
Sonntag,
Ich habe "error: diff: conflicting output style options diff" erhalten, weil ein Diff-Alias ​​definiert wurde. Verwenden Sie which diff, um festzustellen , ob dies Ihr Problem ist.
Justinjhendrick
13
grep -Fxf file1 file2

-FBedeutet, -xdass einfache Zeichenfolgen abgeglichen werden (nicht reguläre Ausdrücke). Bedeutet, dass nur ganze Zeilen abgeglichen werden. Bedeutet, dass -fMuster (dh Linien) aus der als Argument angegebenen Datei entnommen werden

tobyodavies
quelle
3
Sind nicht -fund -Fausgetauscht? Zumindest in meiner grepVersion ist das so. Ich muss file2Input für -fArgumente liefern , wie cat file1 | grep -Fxf file2und dann funktioniert.
Birei
Das funktioniert bei mir nicht.
Chaminda Bandara
7

Ich glaube nicht, dass es einen einzigen Befehl gibt, der das tut, was Sie wollen. Sie können jedoch versuchen, die Ausgabe von diffmit zu kombinieren grep. Wenn Ihre Textdateien keine der Zeichen |, <, >, folgendes Sie etwas Nutzleistung:

$ diff --side-by-side a b | grep -n -v "[|<>]"
3:Hello                             Hello
4:World                             World
Marcel Stimberg
quelle
Versuchen Sie diff --width=155 --left-column --side-by-side a b | grep -n -v '|' | sed 's/ *($//'
Folgendes
das sieht besser aus - aber Sie müssen <und> in das grep aufnehmen, um auch die hinzugefügten Zeilen in beiden Dateien zu entfernen.
Marcel Stimberg
6

commkann verwendet werden. man commfür alle Optionen, aber Sie möchten verwenden comm -12 ..., um nur Zeilen anzuzeigen, die in beiden Eingängen vorhanden sind.

Wie bereits erwähnt, müssen Sie Ihre Eingaben sortzuerst weiterleiten .

Oli
quelle
1
Hm, das funktioniert nur bei gemeinsamen Zeilen, die in beiden Dateien die gleiche Zeilennummer haben.
Maxschlepzig
2
comm scheint nur für sortierte Dateien zu sein und nicht für die Verwendung des OPs. Sein Beispiel: $ comm -12 ab Hallo Welt comm: Datei 1 ist nicht sortiert comm: Datei 2 ist nicht sortiert
Marcel Stimberg
@maxschlepzig: Sie sollten Ihre Dateien sortieren, bevor Sie sie an comm übergeben.
Hemant
2
Durch das Sortieren werden Sie jedoch alle Informationen über die Position der gemeinsamen Zeilen los. Sie würden Dateien auch nicht sortieren, bevor Sie sie mit diff vergleichen.
Marcel Stimberg
2

Dick Grune hat eine Reihe von Tools für diese Art von Dingen geschrieben:

http://dickgrune.com/Programs/similarity_tester/

Es gibt Versionen, die die Syntax verschiedener Sprachen analysieren, sodass Dinge wie umbenannte Variablen als unverändert angesehen werden können.

Es ist wie similarity-testerin Debian und Ubuntu gepackt.

Douglas Bagnall
quelle