claim.gif
Linux Magazin Linux User Easy Linux Ubuntu User International Linux Community
Erschienen in EasyLinux 10/2004   »   Ausgabe bestellen

Dateien vergleichen mit diff und KDiff3

Der feine Unterschied

von Heike Jurzik


Auf der Kommandozeile vergleicht man Textdateien mit diff. Wir zeigen, wie Sie die Unterschiede farblich hervorgehoben in einem Text-Editor betrachten und mit diff3 gleich drei Dateien vergleichen.

Manchmal sieht man den Wald vor lauter Bäumen nicht -- zwei Textdateien miteinander zu vergleichen, kann ziemlich mühselig sein, und ein zusätzliches Komma als einziger Unterschied verschwindet wie die berühmte Stecknadel im Heuhaufen. Wie gut, dass es unter Linux die diffutils mit den beiden Programmen diff und diff3 gibt, die das Auspüren von Unterschieden in Textdateien automatisieren.

Wer den Output auf der Kommandozeile in Schwarz und Weiß nicht übersichtlich genug findet, kann die Ausgabe von diff und diff3 in eine Datei umleiten und sich das Syntax Highlighting von Text-Editoren zu Nutze machen, das alles in einen Farbtopf taucht.

Als grafische Alternative zur Arbeit auf der Kommandozeile stellen wir KDiff3 vor, das Sie wahlweise aus der Shell mit verschiedenen Optionen aufrufen oder interaktiv per Mausklick bedienen können.

Differenziert

Mit dem Kommando diff vergleichen Sie zwei Textdateien auf der Konsole. Dabei lautet der grundsätzliche Aufruf immer

diff datei1 datei2

Wer einfach nur prüfen möchte, ob sich zwei Dateien unterscheiden, hängt zunächst die Option -q an den Befehl diff an. Das Kommando verrät dann:

$ diff -q bla.txt blubb.txt
Dateien bla.txt und blubb.txt sind verschieden.

Gibt es keine Unterschiede, schweigt diff, und Sie sehen nach kurzer Zeit wieder den Eingabe-Prompt. Um die Unterschiede genauer aufzulisten, lassen Sie den Parameter -q weg:

$ diff bla.txt blubb.txt
1c1
< Hallo, das hier ist eine einfache Textdatei für den EasyLinux-Artikel
---
> Hallo, das hier ist eine einfache Textdatei für den EasyLinux-Text
3,4c3

Um dieses und auch die folgenden Beispiele zu verstehen, ist es wichtig zu wissen, dass diff immer anzeigt, was in der ersten Datei geändert werden muss, damit sie der zweiten Textdatei entspricht (also im Prinzip "erste Datei + Änderungen aus diff = zweite Datei").

Der Output dieses ersten diff-Aufrufs verrät einiges: Das kryptische Kürzel 1c1 bedeutet beispielsweise, dass sich beide Dateien in Zeile 1 voneinander unterscheiden (c steht für das englische "change"). Danach folgen die Ausgabe der entsprechenden Zeile der ersten Datei (beginnend mit <), eine Trennlinie und die passende Zeile aus der zweiten Datei (beginnend mit >).

Enthält die zweite Datei einen ganzen Abschnitt, der in der ersten Datei nicht vorkommt, ist das übrigens kein Problem für diff: Die Zeilen vor und nach dem neuen Abschnitt werden trotz geänderter Zeilennummern weiterhin als identisch erkannt und miteinander verglichen.

Zeilen, die in der zweiten Datei zusätzlich vorhanden sind (in der ersten also fehlen), macht diff anders kenntlich gemacht:

19a19,20
> Hier steht eine Zeile, die in bla.txt gar nicht ist :) Ob diese Zeilen
> komplett überflüssig sind, bleibt abzuwarten...

Zunächst erscheint wieder die Zeilennummer der ersten Datei. Das a steht für "append" (anhängen) und bedeutet hier, dass hinter Zeile 19 der ersten Datei die Zeilen 19 bis 20 der zweiten Datei angehängt werden müssen, um die beiden Dateien anzugleichen. Wären in der zweiten Datei mehr als zwei neue Zeilen angehängt, würden diese ebenfalls durch Kommata voneinander getrennt angezeigt, also beispielsweise 19,25 als Hinweis darauf, dass die Zeilen 19 bis 25 neu hinzugekommen sind.

Aus dem Kontext gerissen?

Wer gerne etwas mehr Kontext sieht, setzt die Option -c ein: Jetzt zeigt diff zu jeder Zeile mit Änderungen die drei vorangehenden und folgenden Zeilen an und markiert darin die Unterschiede (siehe Kasten "diff mit Kontext").

diff mit Kontext
$ diff -c bla.txt blubb.txt
*** bla.txt     2004-08-14 16:48:34.000000000 +0200
--- blubb.txt   2004-08-14 16:49:39.000000000 +0200
***************
*** 1,7 ****
! Hallo, das hier ist eine einfache Textdatei für den EasyLinux-Artikel
  zum Thema diff.
!
! Hier steht einfach zufälliger Text:
--- 1,6 ----
! Hallo, das hier ist eine einfache Textdatei für den EasyLinux-Text
  zum Thema diff.
! Hier steht einfach zufälliger Text ->

diff zeigt am Anfang der Ausgabe für beide Dateien den Namen und das Datum der letzten Änderung an. Außerdem verrät die Ausgabe, dass Angaben zur ersten Datei mit Sternchen und Informationen zur zweiten Datei mit Strichen gekennzeichnet werden. Als Nächstes folgen die Zeilen 1 bis 7 der ersten Datei -- Zeilen, die von der zweiten Datei abweichen, haben ein Ausrufezeichen vorangestellt. Neu hinzugekommene Abschnitte behandelt diff auch hier gesondert, sie haben ein Pluszeichen am Zeilenanfang:

[...]
+ Hier steht eine Zeile, die in bla.txt gar nicht ist :) Ob diese Zeilen
+ komplett überflüssig sind, bleibt abzuwarten...

Entsprechend kennzeichnet diff fehlende Zeilen mit einem Minuszeichen vor der Zeile. Standardmäßig merkt das Tool fehlende oder neu hinzugekommene Leerzeilen und auch Leerzeichen an. Wer die leeren Zeilen ignorieren möchte, verwendet den Parameter -B. Um die Leerzeichen zu unterdrücken, hängen Sie die Option -b an.

Wer die Unterschiede zwar im Zusammenhang, aber direkt hintereinander sehen möchte, verwendet statt -c den Parameter -u (siehe Kasten "diff im Unified-Format").

diff im "Unified"-Format
$ diff -u bla.txt blubb.txt
--- bla.txt     2004-08-14 16:48:34.000000000 +0200
+++ blubb.txt   2004-08-14 16:49:39.000000000 +0200
@@ -1,7 +1,6 @@
-Hallo, das hier ist eine einfache Textdatei für den EasyLinux-Artikel
+Hallo, das hier ist eine einfache Textdatei für den EasyLinux-Text
 zum Thema diff.
-
-Hier steht einfach zufälliger Text:
+Hier steht einfach zufälliger Text ->

Hier markiert diff die Dateien nicht mit Sternchen und Strichen, sondern mit Minus- und Pluszeichen. Zwischen den zwei "@"-Zeichen, die als Trenner verwendet werden, steht jeweils, welche Zeilen diff miteinander verglichen hat. In der Beispielausgabe sind das die Zeilen 1 bis 7 der ersten Datei (zu erkennen am Minuszeichen) und die Zeilen 1 bis 6 der zweiten Datei (durch das Pluszeichen markiert).

Übersichtlich

Gerade bei längeren Textdateien kommt es vor, dass die diff-Ausgabe einfach aus dem Fenster heraus scrollt. Leiten Sie die Ausgabe einfach über das Pipe-Zeichen "|" an den Pager less weiter und betrachten Sie die Unterschiede seitenweise:

diff -u bla.txt blubb.txt | less

In less blättern Sie mit den Pfeiltasten zeilenweise, mit den [Bild hoch]- und [Bild runter]-Tasten seitenweise hoch und runter; mit [Q] verlassen Sie den Pager.

Noch übersichtlicher und schön bunt wird es, wenn Sie die diff-Ausgabe in eine Datei umleiten und diese mit einem Editor, wie z. B. Kate oder KWrite, betrachten. Das Syntax Highlighting leistet in diesem Fall ganze Arbeit und gestaltet die Informationen farbig. Dabei stellt der Editor jedoch lediglich die Zeilen der jeweiligen Datei in unterschiedlichen Farben dar, nicht die abweichenden Textstellen selbst.

Um die Befehlsausgabe in eine Datei umzuleiten, rufen Sie zunächst diff wie folgt auf:

diff bla.txt blubb.txt > text.diff

Öffnen Sie anschließend die Datei text.diff in Kate oder KWrite -- neben den schon bekannten Informationen und den Trennlinien erscheinen die Zeilen der einzelnen Dateien farbig markiert (Abbildung 1).

Abb. 1: Farbenzauber: Kates Syntax Highlighting taucht die "diff"-Ausgabe in den Farbtopf.

Wenn Sie Kates Ansicht in zwei Hälften aufteilen, können Sie in der linken Fensterhälfte beispielsweise die erste Datei bearbeiten und angleichen, während Sie rechts die diff-Ausgabe anschauen (Abbildung 2).

Abb. 2: Geteiltes Fenster, doppelte Freude -- mit Kate legen Sie die "diff"-Ausgabe zum Vergleich daneben.

Zu dritt

Das diffutils-Paket bietet auch ein Programm, das drei Textdateien vergleicht. Der Befehl lautet

diff3 datei1 datei2 datei3

-- die Ausgabe sieht geringfügig anders aus als die von diff:

$ diff3 blabb.txt blubb.txt bla.txt
====2
1:1c
3:1c
  Hallo, das hier ist eine einfache Textdatei für den EasyLinux-Artikel
2:1c
  Hallo, das hier ist eine einfache Textdatei für den EasyLinux-Text

Hinter den drei Trennzeichen (===) steht die Nummer der Datei, die an dieser Stelle von den anderen abweicht. (Fehlt die Nummer, sind alle Dateien unterschiedlich.) Es folgen die Zeilennummern und die Ausgabe der Zeile selbst, so dass der Vergleich übersichtlicher wird. Im Beispiel unterscheidet sich die zweite Datei (also blubb.txt) von den beiden anderen. Die detaillierte Ausgabe verrät, in welchen Zeilen die Unterschiede sind.

Genau wie bei diff steht das c in der Ausgabe wieder für "change"; gibt es zusätzliche Zeilen, wird das wieder durch a (für "append", anhängen) deutlich gemacht:

[...]
====3
1:19a
2:19a
3:20c
  Eine total überflüssige Zeile :)

In der ersten und zweiten Datei müsste also jeweils an die 19. Zeile etwas angehängt werden, damit die drei Dateien gleich sind. Was da angehängt werden soll, steht auch in der Ausgabe: Die 20. Zeile in Datei 3 lautet "Eine total überflüssige Zeile :)".

Diff per Mausklick

Für alle, die lieber grafisch arbeiten, gibt es das Programm KDiff3, das bis zu drei Textdateien miteinander vergleicht und auf Wunsch sogar zusammenführt. Praktischerweise übernimmt KDiff3 auch Editor-Aufgaben, so dass Sie Änderungen direkt in diesem Programm durchführen können.

KDiff3 ist standardmäßig nicht auf den Installations-CDs der von EasyLinux unterstützten Distributionen enthalten. Unter der Adresse http://sourceforge.net/project/showfiles.php?group_id=58666&package_id=54597 gibt es aber RPM-Pakete für alle Systeme. Am einfachsten ist die Installation über den Konqueror (oder Nautilus), wenn Sie dem Link zum Paket folgen und es mit dem jeweiligen Paket-Manager Ihrer Distribution einspielen.

Um zwei oder drei Dateien miteinander zu vergleichen, geben Sie die Dateinamen nach dem Start von KDiff3 in die Dialogbox ein. Noch einfacher ist es, KDiff3 von der Kommandozeile aus mit der Angabe der Dateinamen zu starten, also z. B.:

kdiff3 bla.txt blubb.txt

KDiff3 setzt nicht nur an den Zeilenanfang eine Markierung, sondern färbt auch die betroffenen Textstellen selbst ein (Abbildung 3). Auf Wunsch können Sie Zeilennummern ein- und ausblenden und Textstellen (in allen Dateien gleichzeitig) suchen.

Abb. 3: KDiff3 markiert die Unterschiede im Text und nicht nur die betroffenen Zeilen.

Praktisch ist vor allem das automatische Zusammenführen von Dateien, das man einsetzen kann, wenn es zwei (von verschiedenen Benutzern) geänderte Versionen einer Originaldatei gibt. Diese Funktion rufen Sie entweder aus dem Menü heraus auf oder geben auf der Kommandozeile die Option -m an:

kdiff3 bla.txt blubb.txt -m

Der Parameter -m steht dabei für "merge" ("zusammenführen"); bei Bedarf geben Sie direkt eine Ausgabedatei an, in der die "Dateimischung" landet; dazu verwenden Sie beim Programmaufruf die Option -o ausgabedatei. Standardmäßig nimmt KDiff3 die erste Datei als Basis für alle anderen -- soll stattdessen die zweite oder dritte Datei als Grundlage herangezogen werden, teilen Sie KDiff3 dies über -b datei(2/3) mit.

Kommt es beim Zusammenführen zu einem "Konflikt", den KDiff3 nicht selbständig lösen kann, weist das Programm nicht nur darauf hin, sondern zeigt in einem eigenen Fenster auch die problematischen Stellen an (Abbildung 4). (hge)

Abb. 4: Schlägt das automatische Zusammenführen fehl, zeigt KDiff3 die problematischen Stellen an.

Dieser Online-Artikel kann Links enthalten, die auf nicht mehr vorhandene Seiten verweisen. Wir ändern solche "broken links" nur in wenigen Ausnahmefällen. Der Online-Artikel soll möglichst unverändert der gedruckten Fassung entsprechen.

Druckerfreundliche Version | Feedback zu dieser Seite | Datenschutz | © 2014 Medialinx AG | Last modified: 2007-01-25 17:21

[Linux-Magazin] [LinuxUser] [Linux-Community] [Admin-Magazin] [Ubuntu User] [Smart Developer] [Linux Events] [Linux Magazine] [Ubuntu User] [Admin Magazine] [Smart Developer] [Linux Magazine Poland] [Linux Community Poland] [Linux Magazine Brasil] [Linux Magazine Spain] [Linux Technical Review]