Startseite>Mit Diff Unterschiede in Dateien aufspüren
Aus Raspberry Pi Geek 06/2020

Mit Diff Unterschiede in Dateien aufspüren

© Damedeeso, 123RF

Spurensuche

Harald Zisler

Welche Version einer Datei liegt vor? Die richtigen Tools beantworten diese Frage mit nur einem Kommando.

Gleich von Anfang an lohnt es sich, mit der alten Mär aufzuräumen, dass Sie Unterschiede zwischen Dateien bereits an deren Größe erkennen. Das mag gelegentlich stimmen, aber eine Garantie dafür gibt es nicht. Listing 1 zeigt drei gleich große Dateien. In 2.txt unterscheidet sich aber in einer Zeile die Schreibweise der Zeichen: ABCdef statt abcDEF. Verlassen Sie sich also nicht auf die Abfrage von Metadaten.

Listing 1

$ ls -l
-rw-r--r-- 1 artikel artikel 60 Nov  9 08:59 1.txt
-rw-r--r-- 1 artikel artikel 60 Nov  9 08:59 2.txt
-rw-r--r-- 1 artikel artikel 60 Nov  9 08:59 3.txt

Beispieldaten

Als Datenbasis für die Beispiele in diesem Beitrag dienen als Textdateien die Files 1.txt, 2.txt und 3.txt, wobei 1.txt und 3.txt identisch sind. Außerdem kommen die PDF-Dateien 1.pdf, 2.pdf und 3.pdf zum Einsatz, wobei wiederum 1.pdf und 3.pdf identisch sind. Die Dateien befinden sind in den Verzeichnissen erstes, zweites und drittes, wobei der Inhalt von erstes und drittes gleich ist.

Übersicht

Die Diff-Tools eignen sich für den Einsatz in Shell-Skripten oder die Arbeit auf dem Desktop. Manche Programme vergleichen nur Textdateien, wobei die Möglichkeiten trotzdem vielfältig ausfallen: Von Quelltext über Markup-Dateien bis hin zu strukturierten Textdateien im CSV-Format eignen sich zahlreiche Varianten als Ausgangsmaterial. Andere Tools bearbeiten sogar Binärdateien. Die Tabelle “Diff-Kommandos” zeigt eine Auswahl der Befehle.

Befehl

vergleicht

Hinweise

diff

Textdateien, Verzeichnisinhalte, Binärdateien

für Shell-Skripte geeignet

numdiff

Textdateien (mit numerischem Inhalt)

für Shell-Skripte geeignet

duff

Textdateien/Binärdateien/Verzeichnisinhalte

listet nur Duplikate auf, für Shell-Skripte geeignet

fcomp

Textdateien/Binärdateien

für Shell-Skripte geeignet, eventuell weitere Hilfsmittel notwendig

icdiff

Textdateien

für Shell-Skripte geeignet, eventuell weitere Hilfsmittel notwendig

difference

Zeichenketten

Für Shell-Skripte geeignet, weitere Hilfsmittel wie Wc notwendig

latexdiff

Latex-Dateien

im Shell-Skript, weitere Hilfsmittel notwendig

ssh-diff

Dateien per SSH

für Shell-Skripte bedingt geeignet, weitere Hilfsmittel notwendig

vbindiff

Binär- und Textdateien

Shell, benutzergeführt

comparepdf

PDF-Dateien

für Shell-Skripte geeignet

diffpdf

PDF-Dateien

GUI, benutzergeführt

diffimg

Bilddateien

Formate: PNG, GIF, JPEG, Vergleich PS mit GS

diffuse

Textdateien

GUI, benutzergeführt

meld

Textdateien

GUI, benutzergeführt

Generalist

Als universelles Werkzeug eignet sich Diff besonders für den Einsatz in einem Shell-Skript. Dieses Programm findet sich praktisch auf allen Linux- und BSD-Systemen. Abbildung 1 zeigt den Einsatz in der Shell mit Abfrage des Exit-Codes. Dabei steht der Rückgabewert 0 für zwei identische, 1 für unterschiedliche Dateien oder Verzeichnisse. Die Option -q unterdrückt umfangreiche Ausgaben. Abbildung 2 zeigt den Vergleich zweier PDF-Dateien und zweier Verzeichnisse.

Abbildung 1: Der Vergleich zweier Textdateien mit Diff, wobei der Exit-Code bereits Auskunft über mögliche Unterschiede gibt.

Abbildung 1: Der Vergleich zweier Textdateien mit Diff, wobei der Exit-Code bereits Auskunft über mögliche Unterschiede gibt.

Abbildung 2: Beim Vergleich anderer Dateitypen und von Verzeichnissen leistet Diff ebenfalls gute Dienste.

Abbildung 2: Beim Vergleich anderer Dateitypen und von Verzeichnissen leistet Diff ebenfalls gute Dienste.

Mit der Option -s weisen Sie Diff an, identische Dateien anzuzeigen. Das erleichtert das Aufspüren von Duplikaten. Listing 2 zeigt, wie Sie eine Tabelle erzeugen, die zu jedem Objekt gegebenenfalls auch das Duplikat aufzählt.

Listing 2

#! /bin/bash
# Positionsparameter: $1 = Verzeichnis
if [ -z $1 ]; then
  echo "Eingabe: Listing1.sh VERZEICHNIS"
  exit
fi
cd $1
# Duplikate mit Fiff finden
for i in $(ls -1); do
  for k in $(ls -1 | sort -r); do
    if [ "$i" = "$k" ]; then
      # Falls Vergleich eines Objekts mit
      # sich selbst, gehe ans Schleifenende
      continue
    fi
    diff -sq $i $k 2> /dev/null | grep -v "diff:" | grep identisch
  done
done
cd

Abbildung 3 zeigt den Ablauf mit den Musterdaten. Die Liste fällt in anderen Fällen unter Umständen sehr umfangreich aus, da das Skript dann eventuell sogar Dateien in Unterverzeichnissen miteinander vergleicht.

Abbildung 3: Das Skript aus <a href="#artRef-l2">Listing&nbsp;2</a> untersucht eine Reihe von Dateien und zeigt an, ob sie sich unterscheiden oder identisch sind.

Abbildung 3: Das Skript aus Listing 2 untersucht eine Reihe von Dateien und zeigt an, ob sie sich unterscheiden oder identisch sind.

Duplikate finden

Speziell zum Auflisten von doppelten Inhalten eignet sich Duff. Sie übergeben dem Kommando ein Suchmuster, damit die Suche gelingt, also mindestens *. Von Haus aus unterbleibt der Vergleich von Unterverzeichnissen, außer Sie fordern das explizit mit der Option -r an. Beim Einsatz in einem Shell-Skript benötigen Sie nur die Angabe der Duplikate selbst, was Sie mittels -e anfordern.

Abbildung 4 stellt die Grundfunktionen anschaulich dar. Zuerst finden Sie die “Grundform”. Anzahl der übereinstimmenden Dateien, Original- und Duplikat-Datei werden aufgelistet. Die Anzeige von Duplikaten bei den Textdateien im aktuellen Verzeichnis zeigt das zweite Beispiel, zum Schluss sehen Sie den Vergleich aller Dateien und Verzeichnisse mit der Auflistung der Duplikate.

Abbildung 4: Mit Duff geht die Suche nach Duplikaten noch leichter, da die Software genau auf diesen Zweck zugeschnitten ist.

Abbildung 4: Mit Duff geht die Suche nach Duplikaten noch leichter, da die Software genau auf diesen Zweck zugeschnitten ist.

Nachdem Duff speziell Duplikate aufspürt, liegt der Einsatz in einem Skript nahe. In Listing 3 finden Sie ein Skript, das Duplikate mit oder ohne Rückfrage entfernt. Die Rückfrage erhalten Sie durch die Option -i beim Befehl rm. Abbildung 5 zeigt, wie das in der Praxis aussieht.

Listing 3

#! /bin/bash
# Löschen von Duplikaten
echo "Gefundene Duplikate:"
duff -re .
echo "------------------------------------"
read -p "Alle löschen (A), Löschen mit Nachfrage (f), ABBRUCH (ENTER) " we
if [ -z $we ]; then
  echo "Keine Aktion gewählt"
  exit
fi
if [ "$we" = "A" ]; then
  for i in $(duff -re .); do
    rm -rv $i
  done
fi
if [ "$we" = "f" ]; then
  for i in $(duff -re .); do
    rm -rvi $i
  done
fi
Abbildung 5: Wollen Sie Duplikate aus einem Verzeichnis entfernen, eignet sich dazu eine Kombination aus Duff mit etwas Shell-Logik.

Abbildung 5: Wollen Sie Duplikate aus einem Verzeichnis entfernen, eignet sich dazu eine Kombination aus Duff mit etwas Shell-Logik.

Zeichenketten vergleichen

Das Shell-Builtin test leistet meist gute Dienste beim Vergleichen von Zeichenketten (Listing 4). Für einen schnellen Vergleich ist so ein Konstrukt jedoch umständlich. Mit Difference gelingt das Auswerten zweier Strings übersichtlicher. Abbildung 6 zeigt die Arbeitsweise des Tools.

Listing 4

if [ "$HOME" = "$PWD" ]; then
  echo "Aktuelles Verzeichnis ist das Heimatverzeichnis"
else
  echo "Aktuelles Verzeichnis ist nicht das Heimatverzeichnis"
fi
DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 8 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
€0,99 – Kaufen
RASPBERRY PI GEEK KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS
Deutschland