diff-Befehl: Dateien vergleichen, das Patch-Format von diff -u und Optionen

TestumgebungRHEL-FamilieAlmaLinux 9.8root-Konto
Befehle zum Anzeigen · Bearbeiten von TextdiffSpeicherort/usr/bin/diff

Der diff-Befehl ist ein Linux-Befehl, der zwei Dateien zeilenweise vergleicht und nur die unterschiedlichen Zeilen ausgibt. Beim Vergleich einer alten und einer neuen Datei, die eine Webserver-Konfiguration nachbilden, zeigte diff die drei geänderten Stellen in den drei Zeilen 2,3c2,3, 5d4 und 6a6, und in der mit der Option -u gespeicherten Patch-Datei standen dieselben Änderungen mit Minus- und Pluszeichen.

Die Dateinamen und Inhalte in der Ausgabe unten sowie der Arbeitsordner /root/work sind Beispielwerte. Alle verglichenen Dateien sind kleine, zum Testen angelegte Dateien.

1️⃣ Grundlegende Verwendung des diff-Befehls und die Ausgabe lesen

Die Grundform des Befehls ist diff, Optionen, erste Datei, zweite Datei, in dieser Reihenfolge. Ausgegeben wird mit Zeilennummern, welche Zeilen geändert, gelöscht oder hinzugefügt werden müssen, damit die erste Datei der zweiten gleicht.

Die beiden für den Vergleich verwendeten Dateien sind sechszeilige Dateien, die eine Webserver-Konfiguration nachbilden.

cd /root/work
cat config-old.conf
# app config
listen 80
server_name example.com
root /var/www/html
gzip off
log_level warn
cat config-new.conf
# app config
listen 443
server_name example.com www.example.com
root /var/www/html
log_level warn
cache on

Die beiden Dateien wurden ohne Optionen verglichen.

diff config-old.conf config-new.conf
2,3c2,3
< listen 80
< server_name example.com
---
> listen 443
> server_name example.com www.example.com
5d4
< gzip off
6a6
> cache on
echo $?
1

In der Ausgabe wechseln sich Positionszeilen und Inhaltszeilen ab. Der mittlere Buchstabe einer Positionszeile steht bei c für Ändern, bei d für Löschen und bei a für Hinzufügen; links vom Buchstaben stehen die Zeilennummern der ersten Datei, rechts die der zweiten. Gibt es Unterschiede, ist der Exit-Code 1.

AusgabeBedeutung
2,3c2,3Ändert die Zeilen 2–3 der ersten Datei in die Zeilen 2–3 der zweiten Datei (change)
5d4Löscht Zeile 5 der ersten Datei (delete). Danach passt die Stelle hinter Zeile 4 der zweiten Datei
6a6Fügt Zeile 6 der zweiten Datei hinter Zeile 6 der ersten Datei ein (add)
< ZeileZeile aus der ersten Datei
> ZeileZeile aus der zweiten Datei
---Grenze zwischen der Seite der ersten Datei und der Seite der zweiten Datei bei geänderten Zeilen (c)

Beim Vergleich von Dateien mit gleichem Inhalt wird nichts ausgegeben, und der Befehl endet mit dem Exit-Code 0.

diff config-old.conf config-copy.conf
echo $?
0

Wird eine Datei angegeben, die es nicht gibt, erscheint eine Fehlermeldung, und der Exit-Code ist 2.

diff config-old.conf nosuch.conf
diff: nosuch.conf: No such file or directory
echo $?
2

In einem Skript lassen sich mit diesen drei Werten gleich, unterschiedlich und Fehler unterscheiden.

2️⃣ Das Unified-Format von diff -u und Patch-Dateien

Die normale Ausgabe zeigt nur die geänderten Zeilen, sodass in einer Konfigurationsdatei mit Hunderten von Zeilen schwer zu erkennen ist, in der Nähe welcher Einstellung sie liegen. Mit -u erfolgt die Ausgabe im Unified-Format (unified), das bis zu drei Zeilen vor und nach den geänderten Zeilen mit zusammenfasst.

diff -u config-old.conf config-new.conf
--- config-old.conf     2026-10-29 02:24:50.840228932 +0000
+++ config-new.conf     2026-10-29 02:24:50.840228932 +0000
@@ -1,6 +1,6 @@
 # app config
-listen 80
-server_name example.com
+listen 443
+server_name example.com www.example.com
 root /var/www/html
-gzip off
 log_level warn
+cache on

Die beiden Kopfzeilen (---, +++) zeigen Namen und Änderungszeit der beiden Dateien, und die Zeile @@ -1,6 +1,6 @@ steht für einen Block (hunk), der 6 Zeilen ab Zeile 1 der ersten Datei und 6 Zeilen ab Zeile 1 der zweiten Datei zusammenfasst. In den Zeilen darunter bedeutet ein - am Anfang eine aus der ersten Datei gelöschte Zeile, ein + eine zur zweiten Datei hinzugefügte Zeile und ein Leerzeichen eine Zeile, die in beiden Dateien gleich ist.

-c ist das Kontextformat (context). Der Block der ersten Datei und der Block der zweiten Datei werden getrennt ausgegeben, mit einem Ausrufezeichen vor geänderten Zeilen, einem Minuszeichen bei gelöschten und einem Pluszeichen bei hinzugefügten Zeilen.

diff -c config-old.conf config-new.conf
*** config-old.conf     Thu Oct 29 02:24:50 2026
--- config-new.conf     Thu Oct 29 02:24:50 2026
***************
*** 1,6 ****
  # app config
! listen 80
! server_name example.com
  root /var/www/html
- gzip off
  log_level warn
--- 1,6 ----
  # app config
! listen 443
! server_name example.com www.example.com
  root /var/www/html
  log_level warn
+ cache on

Bei denselben Änderungen wurde -c länger als -u, weil die unveränderten Zeilen in beiden Blöcken je einmal erscheinen.

Wird die Ausgabe von -u in einer Datei gespeichert, ist diese Datei bereits die Patch-Datei. Auch wenn die Ausgabe in eine Datei geleitet wird, bleibt der Exit-Code von diff 1.

diff -u config-old.conf config-new.conf > /root/work/config.patch
echo $?
1
cat /root/work/config.patch
--- config-old.conf     2026-10-29 02:24:50.840228932 +0000
+++ config-new.conf     2026-10-29 02:24:50.840228932 +0000
@@ -1,6 +1,6 @@
 # app config
-listen 80
-server_name example.com
+listen 443
+server_name example.com www.example.com
 root /var/www/html
-gzip off
 log_level warn
+cache on

Der Inhalt der gespeicherten Datei entspricht dem auf dem Bildschirm ausgegebenen Ergebnis von -u. Wird diese Datei an den Befehl patch übergeben, lässt sich die erste Datei auf den Inhalt der zweiten bringen.

3️⃣ diff-Optionen und das Ignorieren von Leerzeichen und Groß-/Kleinschreibung

Beim Abschreiben einer Konfiguration von Hand entstehen Zeilen, die inhaltlich gleich sind und sich nur in Groß-/Kleinschreibung oder Leerzeichen unterscheiden. Im zweiten Paar von Beispieldateien wurde das große L der ersten Zeile klein geschrieben, aus einem Leerzeichen in der zweiten Zeile wurden zwei, und eine Leerzeile kam hinzu.

cat case-a.txt
Listen 80
ServerName example.com
DocumentRoot /var/www/html
cat case-b.txt
listen 80
ServerName  example.com

DocumentRoot /var/www/html
diff case-a.txt case-b.txt
1,2c1,3
< Listen 80
< ServerName example.com
---
> listen 80
> ServerName  example.com
>

Ohne Optionen erscheinen auch die gleichbedeutenden Zeilen 1–2 als geänderte Zeilen. Wird mit -i die Groß-/Kleinschreibung ignoriert, fällt die Listen-Zeile weg, und nur Zeile 2 der ersten Datei bleibt übrig.

diff -i case-a.txt case-b.txt
2c2,3
< ServerName example.com
---
> ServerName  example.com
>

Mit zusätzlichem -w werden alle Leerzeichen innerhalb einer Zeile ignoriert, sodass auch die ServerName-Zeile als gleich gilt und nur die in Zeile 3 hinzugefügte Leerzeile übrig bleibt. Mit -b, das nur die Anzahl der Leerzeichen ignoriert, statt -w ergab sich bei diesen Dateien dasselbe Ergebnis.

diff -i -w case-a.txt case-b.txt
2a3
>

Kommt noch -B hinzu, werden auch Unterschiede bei Leerzeilen ignoriert, sodass der Befehl ohne Ausgabe mit dem Exit-Code 0 endete.

diff -i -w -B case-a.txt case-b.txt
echo $?
0

Um die beiden Dateien links und rechts nebeneinander zu sehen, wird -y verwendet. Die Standardbreite beträgt 130 Spalten und wurde deshalb mit -W 70 verkleinert.

diff -y -W 70 config-old.conf config-new.conf
# app config                            # app config
listen 80                         |     listen 443
server_name example.com           |     server_name example.com www.ex
root /var/www/html                      root /var/www/html
gzip off                          <
log_level warn                          log_level warn
                                  >     cache on

Der senkrechte Strich (|) in der Mitte kennzeichnet eine geänderte Zeile, < eine Zeile nur in der ersten Datei und > eine Zeile nur in der zweiten Datei. Bei geringerer Breite werden lange Zeilen abgeschnitten. Die server_name-Zeile erschien rechts nur bis www.ex.

Mit zusätzlichem --suppress-common-lines werden gleiche Zeilen weggelassen, und nur die unterschiedlichen bleiben.

diff -y --suppress-common-lines -W 70 config-old.conf config-new.conf
listen 80                         |     listen 443
server_name example.com           |     server_name example.com www.ex
gzip off                          <
                                  >     cache on

Soll nur geprüft werden, ob die Dateien gleich oder verschieden sind, und nicht, worin der Unterschied besteht, wird -q verwendet. Sind die Dateien gleich, gibt -q nichts aus; für eine Zeile mit der Meldung, dass sie gleich sind, wird -s verwendet.

diff -q config-old.conf config-new.conf
Files config-old.conf and config-new.conf differ
diff -s config-old.conf config-copy.conf
Files config-old.conf and config-copy.conf are identical

Die Optionen sind in den zwei Tabs unten zusammengefasst.

OptionKopierenBeschreibung
-u, --unifiedAusgabe im Unified-Format, das bis zu drei Zeilen vor und nach den geänderten Zeilen mit zusammenfasst
-c, --contextKontextformat, das den Block der ersten Datei und den Block der zweiten Datei getrennt ausgibt
-i, --ignore-caseIgnoriert Unterschiede in der Groß-/Kleinschreibung
-w, --ignore-all-spaceIgnoriert alle Leerzeichen innerhalb einer Zeile
-b, --ignore-space-changeIgnoriert nur Unterschiede in der Anzahl der Leerzeichen
-B, --ignore-blank-linesIgnoriert Unterschiede bei Leerzeilen
-y, --side-by-sideGibt die beiden Dateien links und rechts nebeneinander aus
-W, --widthNUMLegt die Breite der Ausgabe nebeneinander fest. Standardwert sind 130 Spalten
--suppress-common-linesLässt bei der Ausgabe nebeneinander gleiche Zeilen weg und gibt nur unterschiedliche aus
-q, --briefGibt nur aus, ob die Dateien gleich oder verschieden sind. Bei gleichen Dateien erfolgt keine Ausgabe
-s, --report-identical-filesGibt bei zwei gleichen Dateien eine Zeile mit der Meldung aus, dass sie gleich sind
-r, --recursiveVergleicht auch die Dateien in Unterordnern
OptionKopierenBeschreibung
-U, --unifiedNUMLegt fest, wie viele Zeilen davor und danach im Unified-Format mit ausgegeben werden. Standardwert ist 3
-N, --new-fileBehandelt eine auf einer Seite fehlende Datei als leere Datei
-x, --excludePATSchließt Dateien, deren Name zum Muster passt, vom Vergleich aus
-I, --ignore-matching-linesREIgnoriert einen Unterschied, wenn alle geänderten Zeilen zum Regex passen
-Z, --ignore-trailing-spaceIgnoriert Leerzeichen am Zeilenende
-E, --ignore-tab-expansionIgnoriert Unterschiede, die durch das Umwandeln von Tabs in Leerzeichen entstehen
-a, --textBehandelt alle Dateien als Text
--strip-trailing-crEntfernt vor dem Vergleich den Wagenrücklauf am Zeilenende
--colorWHENFärbt die Ausgabe ein. WHEN ist never, always oder auto
-v, --versionGibt Versionsinformationen aus

🔲 Simulator für den diff-Befehl

Im Simulator unten lässt sich diff mit den Beispieldateien aus dem Artikel direkt eingeben. Mit -u lässt sich eine Patch-Datei speichern, mit -i -w -B und -rq lässt sich vergleichen, und nach dem Hinzufügen einer Zeile zu config-new.conf zeigt ein erneuter Vergleich das geänderte Ergebnis.

Simulator für den diff-Befehldiff · root-Konto
[root@server work]#
Mit den Tasten ↑↓ holst du zuvor eingegebene Befehle zurück.

4️⃣ Ordner vergleichen mit diff -r

Um mehrere Dateien auf einmal zu vergleichen, etwa vor und nach dem Deployment von Website-Dateien, werden statt Dateien Ordnernamen angegeben. Die Beispielordner site-v1 und site-v2 enthalten beide index.html und einen Ordner css, während about.html und contact.html nur auf einer Seite vorhanden sind.

diff site-v1 site-v2
Only in site-v1: about.html
Only in site-v2: contact.html
Common subdirectories: site-v1/css and site-v2/css
diff site-v1/index.html site-v2/index.html
2,3c2,3
< <p>Version 1</p>
< <a href="about.html">About</a>
---
> <p>Version 2</p>
> <a href="contact.html">Contact</a>

Beim Vergleich von Ordnern ohne Optionen erscheinen Dateien, die nur auf einer Seite vorhanden sind, als Zeilen mit [Only in] und Unterordner nur als Zeilen mit [Common subdirectories]; die Dateien in den Unterordnern werden nicht verglichen. Für index.html, das in beiden Ordnern unter demselben Namen liegt, werden die Unterschiede unter der Zeile [diff site-v1/index.html site-v2/index.html] ausgegeben. Mit -r wird auch der geänderte Farbwert in style.css im Ordner css ausgegeben.

diff -r site-v1 site-v2
Only in site-v1: about.html
Only in site-v2: contact.html
diff -r site-v1/css/style.css site-v2/css/style.css
2c2
< h1 { color: #222; }
---
> h1 { color: #0a58ca; }
diff -r site-v1/index.html site-v2/index.html
2,3c2,3
< <p>Version 1</p>
< <a href="about.html">About</a>
---
> <p>Version 2</p>
> <a href="contact.html">Contact</a>

Bei einem Ordner mit vielen Dateien wird zuerst mit -rq die Liste der geänderten Dateien geprüft, und danach werden nur die benötigten Dateien erneut mit diff verglichen.

diff -rq site-v1 site-v2
Only in site-v1: about.html
Only in site-v2: contact.html
Files site-v1/css/style.css and site-v2/css/style.css differ
Files site-v1/index.html and site-v2/index.html differ

🔢 FAQ & empfohlene Inhalte

cmp vergleicht zwei Dateien byteweise und gibt nur die erste abweichende Stelle aus. Der Vergleich der beiden Konfigurationsdateien aus dem Artikel mit cmp ergab die eine Zeile [config-old.conf config-new.conf differ: char 21, line 2]. Verwendet wird cmp, um zu prüfen, ob komprimierte Dateien oder Bilder gleich sind, bei denen ein zeilenweiser Vergleich keinen Sinn ergibt.

Dem Befehl patch werden die Originaldatei und die Patch-Datei nacheinander übergeben ([patch config-old.conf config.patch]). patch ändert die Originaldatei an Ort und Stelle; deshalb wird das Ergebnis mit -o in eine andere Datei geschrieben oder der Patch zuerst auf eine Kopie angewendet.

Mit der Option --color[=WHEN] lässt sich Farbe hinzufügen; an der Stelle von WHEN steht never, always oder auto. --color ohne Wert entspricht auto und färbt nur bei der Ausgabe auf ein Terminal, daher wird --color=always verwendet, wenn die Farbe auch bei der Weitergabe an einen anderen Befehl wie less erhalten bleiben soll.

ℹ️ Affiliate-Hinweis
Die Inhalte dieser Website enthalten Affiliate-Links. Kauft ein Besucher über einen dieser Links ein Produkt oder eine Dienstleistung, erhält die Website vom Verkäufer eine Provision. Der Betrag, den der Käufer zahlt(bei Aktionsrabatten sinkt er ↓), steigt dadurch nicht. Angegebene Preise, Rabatte und Lagerbestände entsprechen dem Stand bei Erstellung und können abweichen; prüfe sie daher vor dem Kauf beim Verkäufer. Produkte werden nach eigenen Kriterien ausgewählt und bewertet, und Provisionen beeinflussen weder die Reihenfolge noch den Inhalt der Bewertungen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Beweisen Sie, dass Sie ein Mensch sind: 4   +   5   =