# diff — Dateien und Verzeichnisse vergleichen

> Dateien und Verzeichnisse zeilenweise mit diff vergleichen — Unified-, Kontext- und Side-by-Side-Format, rekursiver Vergleich und Patch-Dateien.

Source: https://www.jpkc.com/db/cheatsheets/files-text/diff/

<!-- PROSE:intro -->
`diff` vergleicht zwei Dateien zeilenweise und zeigt dir genau, was sich geändert hat – hinzugefügte, entfernte und veränderte Zeilen. Das mit Abstand wichtigste Ausgabeformat ist das Unified-Format (`-u`), das auch Git und `patch` verwenden; daneben gibt es das Kontext-Format (`-c`) und die zweispaltige Side-by-Side-Ansicht (`-y`). Mit `-r` vergleichst du ganze Verzeichnisbäume rekursiv, und über die Umleitung in eine `.patch`-Datei erzeugst du Patches, die sich später mit `patch` wieder anwenden lassen. Praktisch zum Skripten: Der Exit-Code von `diff` ist `0`, wenn die Dateien identisch sind, `1`, wenn sie sich unterscheiden, und `2` bei einem Fehler.
<!-- PROSE:intro:end -->

## Grundlegender Vergleich

`diff <datei1> <datei2>` — Vergleicht zwei Dateien und zeigt die Unterschiede im Standard-Format (normal).

```bash
diff original.txt modified.txt
```

`diff -s <datei1> <datei2>` — Meldet, wenn zwei Dateien identisch sind.

```bash
diff -s config.ini config.ini.bak
```

`diff -q <datei1> <datei2>` — Meldet nur, ob sich Dateien unterscheiden, nicht die eigentlichen Unterschiede.

```bash
diff -q v1.0/app.js v2.0/app.js
```

`diff <datei1> <datei2> > <patch>` — Speichert die diff-Ausgabe in eine Patch-Datei.

```bash
diff original.c fixed.c > bugfix.patch
```

## Ausgabeformate

`diff -u <datei1> <datei2>` — Unified-Format — das gängigste Format, von Git und Patch-Tools genutzt.

```bash
diff -u old/config.php new/config.php
```

`diff -u <datei1> <datei2> -L '<label1>' -L '<label2>'` — Unified-Format mit eigenen Bezeichnern statt Dateinamen im Kopf.

```bash
diff -u old.conf new.conf -L 'production' -L 'staging'
```

`diff -c <datei1> <datei2>` — Kontext-Format — zeigt Änderungen mit umgebenden Kontextzeilen.

```bash
diff -c original.py patched.py
```

`diff -y <datei1> <datei2>` — Side-by-Side-Format — zeigt beide Dateien in parallelen Spalten.

```bash
diff -y left.txt right.txt
```

`diff -y -W <breite> <datei1> <datei2>` — Side-by-Side-Format mit einer bestimmten Spaltenbreite.

```bash
diff -y -W 120 left.txt right.txt
```

`diff --suppress-common-lines -y <datei1> <datei2>` — Side-by-Side-Format, das nur abweichende Zeilen zeigt.

```bash
diff --suppress-common-lines -y old.conf new.conf
```

`diff -e <datei1> <datei2>` — Gibt ein ed-Skript aus, das datei1 in datei2 überführt.

```bash
diff -e original.txt modified.txt
```

## Kontext steuern

`diff -U <n> <datei1> <datei2>` — Unified-Format mit n Kontextzeilen (Standard ist 3).

```bash
diff -U 5 old.js new.js
```

`diff -C <n> <datei1> <datei2>` — Kontext-Format mit n Kontextzeilen.

```bash
diff -C 10 old.py new.py
```

`diff -U 0 <datei1> <datei2>` — Zeigt nur die geänderten Zeilen ohne umgebenden Kontext.

```bash
diff -U 0 before.txt after.txt
```

## Whitespace & Formatierung

`diff -b <datei1> <datei2>` — Ignoriert Änderungen an der Menge des Whitespace.

```bash
diff -b old.py new.py
```

`diff -w <datei1> <datei2>` — Ignoriert alle Whitespace-Unterschiede.

```bash
diff -w old.html new.html
```

`diff -B <datei1> <datei2>` — Ignoriert Änderungen, die nur Leerzeilen einfügen oder löschen.

```bash
diff -B old.css new.css
```

`diff -i <datei1> <datei2>` — Vergleich ohne Beachtung der Groß-/Kleinschreibung.

```bash
diff -i readme.txt README.txt
```

`diff -Z <datei1> <datei2>` — Ignoriert Whitespace am Zeilenende.

```bash
diff -Z old.txt new.txt
```

`diff -E <datei1> <datei2>` — Ignoriert Änderungen durch Tab-Expansion.

```bash
diff -E tabs.py spaces.py
```

`diff --strip-trailing-cr <datei1> <datei2>` — Entfernt abschließende Carriage Returns (nützlich bei Windows- vs. Unix-Zeilenenden).

```bash
diff --strip-trailing-cr unix.txt windows.txt
```

## Verzeichnisvergleich

`diff -r <verzeichnis1> <verzeichnis2>` — Vergleicht zwei Verzeichnisse und ihren Inhalt rekursiv.

```bash
diff -r project-v1/ project-v2/
```

`diff -rq <verzeichnis1> <verzeichnis2>` — Vergleicht Verzeichnisse rekursiv und meldet nur, welche Dateien sich unterscheiden.

```bash
diff -rq /etc/nginx/ /etc/nginx.bak/
```

`diff -r --exclude='<muster>' <verzeichnis1> <verzeichnis2>` — Vergleicht Verzeichnisse, schließt aber Dateien eines Musters aus.

```bash
diff -r --exclude='*.pyc' src/ src-backup/
```

`diff -r --exclude-from=<datei> <verzeichnis1> <verzeichnis2>` — Vergleicht Verzeichnisse und schließt die in einer Datei aufgelisteten Muster aus.

```bash
diff -r --exclude-from=.diffignore old/ new/
```

`diff -r -x '*.log' -x '*.tmp' <verzeichnis1> <verzeichnis2>` — Vergleicht Verzeichnisse und schließt mehrere Muster aus.

```bash
diff -r -x '*.log' -x '*.tmp' -x '.git' prod/ staging/
```

`diff -rq <verzeichnis1> <verzeichnis2> | grep 'Only in'` — Zeigt Dateien, die nur in einem der beiden Verzeichnisse existieren.

```bash
diff -rq src/ src-backup/ | grep 'Only in'
```

## Patch-Workflow

`diff -u <original> <modified> > <datei.patch>` — Erstellt eine Unified-Patch-Datei aus zwei Dateien.

```bash
diff -u main.c main_fixed.c > fix.patch
```

`diff -ruN <verzeichnis1> <verzeichnis2> > <datei.patch>` — Erstellt einen rekursiven Patch für ganze Verzeichnisse (-N behandelt fehlende Dateien als leer).

```bash
diff -ruN project-v1/ project-v2/ > upgrade.patch
```

`patch < <datei.patch>` — Wendet eine Patch-Datei auf das aktuelle Verzeichnis an.

```bash
patch < fix.patch
```

`patch -p1 < <datei.patch>` — Wendet einen Patch an und entfernt die erste Pfadkomponente (üblich bei Git-Patches).

```bash
patch -p1 < upgrade.patch
```

`patch -R < <datei.patch>` — Kehrt einen zuvor angewendeten Patch um (macht ihn rückgängig).

```bash
patch -R < fix.patch
```

`patch --dry-run < <datei.patch>` — Testet einen Patch, ohne ihn tatsächlich anzuwenden.

```bash
patch --dry-run -p1 < upgrade.patch
```

## Farbige & visuelle Ausgabe

`diff --color <datei1> <datei2>` — Zeigt Unterschiede mit farbiger Ausgabe (GNU diff).

```bash
diff --color old.conf new.conf
```

`diff --color=always <datei1> <datei2> | less -R` — Leitet die farbige diff-Ausgabe durch less und erhält dabei die Farben.

```bash
diff --color=always -u old.js new.js | less -R
```

`colordiff <datei1> <datei2>` — Nutzt den colordiff-Wrapper für automatisch eingefärbte Ausgabe.

```bash
colordiff -u config.old config.new
```

`vimdiff <datei1> <datei2>` — Öffnet beide Dateien in Vim mit einer Side-by-Side-Diff-Ansicht.

```bash
vimdiff original.py modified.py
```

## Verwandte Werkzeuge

`sdiff <datei1> <datei2>` — Side-by-Side-Merge-Werkzeug — interaktive Alternative zu diff -y.

```bash
sdiff -o merged.txt left.txt right.txt
```

`diff3 <meine> <original> <ihre>` — Drei-Wege-Diff — vergleicht drei Dateien (nützlich bei Merge-Konflikten).

```bash
diff3 my-branch.txt base.txt their-branch.txt
```

`comm <datei1> <datei2>` — Vergleicht zwei sortierte Dateien zeilenweise (zeigt eindeutige und gemeinsame Zeilen).

```bash
comm -12 sorted1.txt sorted2.txt
```

`cmp <datei1> <datei2>` — Byteweiser Vergleich — meldet den ersten gefundenen Unterschied.

```bash
cmp binary1.dat binary2.dat
```

`wdiff <datei1> <datei2>` — Wortweiser Diff — hebt einzelne Wortänderungen hervor.

```bash
wdiff draft.txt final.txt
```

## Praktische Beispiele

`diff -u <(sort file1.txt) <(sort file2.txt)` — Vergleicht zwei Dateien nach dem Sortieren (per Process Substitution).

`diff <(ssh host1 cat /etc/config) <(ssh host2 cat /etc/config)` — Vergleicht eine Konfigurationsdatei auf zwei entfernten Servern.

`diff -rq src/ deploy/ --exclude='.git' | sort` — Prüft, welche Dateien sich zwischen lokalem Quellcode und ausgerollter Version unterscheiden.

`diff -u /dev/null <neuedatei>` — Erstellt einen Patch, der eine komplett neue Datei hinzufügt.

```bash
diff -u /dev/null src/newfeature.js > add-feature.patch
```

`diff <(xxd file1.bin) <(xxd file2.bin)` — Vergleicht zwei Binärdateien über ihre Hex-Dump-Ausgabe.

`diff -u <datei1> <datei2> | diffstat` — Zeigt eine Zusammenfassung der Änderungen (Einfügungen, Löschungen pro Datei).

```bash
diff -ruN v1/ v2/ | diffstat
```

`diff -y -W 80 <(curl -s <url1>) <(curl -s <url2>)` — Vergleicht den Inhalt zweier URLs Side-by-Side.

`find . -name '*.bak' -exec sh -c 'diff -q "$1" "${1%.bak}"' _ {} \;` — Vergleicht jede .bak-Datei mit ihrem Original.

<!-- PROSE:outro -->
## Fazit

`diff` ist das Standardwerkzeug, um Änderungen zwischen zwei Ständen sichtbar zu machen – ob beim Vergleich zweier Konfigurationen, beim Reviewen von Code oder beim Aufspüren von Drift zwischen Quellcode und Deployment. Für den Alltag merkst du dir vor allem `-u` (Unified, das Git-/Patch-Format), `-r` (rekursiv über Verzeichnisse) und `-q` (nur melden, was abweicht). Der Exit-Code macht `diff` skripttauglich: `0` gleich, `1` unterschiedlich, `2` Fehler. Einige Flags wie `-Z`, `-E` oder `--color` sind GNU-Erweiterungen und fehlen auf BSD/macOS. Für die Ausgabe lohnt sich `less -R` zum Blättern mit erhaltenen Farben; zum Filtern der Treffer greifst du zu `grep`, für skriptgesteuerte Textänderungen zu `sed`.

## Weiterführende Links

- [ubuntuusers-Wiki: diff](https://wiki.ubuntuusers.de/diff/) – deutschsprachige Einführung in Vergleich und Patch-Erstellung
- [GNU Diffutils-Handbuch](https://www.gnu.org/software/diffutils/manual/html_node/index.html) – offizielle Referenz zu allen Formaten und Optionen (englisch)
<!-- PROSE:outro:end -->

## Verwandte Kommandos

- [grep](https://www.jpkc.com/db/cheatsheets/files-text/grep/) – Zeilen nach Mustern filtern, oft auf diff-Ausgabe angewendet
- [sed](https://www.jpkc.com/db/cheatsheets/files-text/sed/) – Text skriptgesteuert ersetzen und transformieren
- [less](https://www.jpkc.com/db/cheatsheets/files-text/less/) – Ausgabe seitenweise durchblättern, mit -R für Farben

