Verzeichnisse vergleichen mit PowerShell

    Verzeichnisse vergleichenWenn man den Inhalt von Ordnern oder ganzen Verzeichnis­bäumen ver­gleichen möchte, dann bietet PowerShell dafür kein eigenes Cmdlet an. Die Auf­gabe lässt sich aber relativ elegant mit einer Kombi­nation aus Get-ChildItem und Compare-Object lösen.

    Windows enthält schon lange das Dienstprogramm comp.exe, mit dem sich Dateien vergleichen lassen. Wenn man ihm die Namen von Verzeich­nissen übergibt, dann prüft es alle darin enthaltenen gleich­namigen Dateien auf Unterschiede. Das ist jedoch nicht, was man normalerweise möchte.

    Ergebnisse von dir oder gci vergleichen

    Als Alternative bliebe dann, dass man den dir-Befehl auf beide Verzeichnisse anwendet und die Ausgabe jeweils in eine eigene Datei umleitet. Diese Dateien kann man dann mit comp.exe oder fc.exe vergleichen. Ganz ähnlich ist das Vorgehen in PowerShell, das aber nicht einmal ein eigenes Cmdlet für das Vergleichen von Dateien hat (siehe dazu: Dateien vergleichen in PowerShell).

    Hier liest man den Inhalt der Verzeichnisse mit Get-ChildItem (Alias gci), dem Äquivalent zum alten dir-Befehl, aus. Dessen Ergebnisse muss man jedoch nicht in Dateien zwischen­speichern, sondern kann sie Compare-Object als Parameter übergeben.

    Der Side Indicator zeigt an, in welchem Verzeichnis eine Datei gefunden wurde, die auf der anderen fehlt.

    Im einfachsten Fall könnte ein Vergleich von 2 Verzeichnissen so aussehen:

    Compare (gci .\) (gci Archiv)

    Dieser Aufruf sollte herausfinden, ob bzw. welche Dateien nur im aktuellen Verzeichnis oder nur im Unter­verzeichnis Archiv existieren. Gibt es eine Datei nur im aktuellen Verzeichnis, dann zeigt der Pfeil des so genannten Side Indicator nach links, sind welche nur unter .\Archiv vorhanden, dann zeigt er nach rechts.

    Gleichnamige Dateien anzeigen

    Ist man nicht an den Unterschieden zwischen den Verzeichnissen interessiert, sondern an den Dateien, die in beiden Verzeichnissen vorkommen, weil man etwa Dubletten finden möchte, dann muss man den Vergleich umdrehen:

    Compare (gci .\) (gci Archiv) -IncludeEqual -ExcludeDifferent

    Der Schalter IncludeEqual alleine reicht hier nicht, weil auch die Unterschiede angezeigt würden. Daher muss man zusätzlich ExcludeDifferent angeben.

    Inverser Vergleich mit den Parametern IncludeEqual und ExcludeDifferent

    Verzeichnisse rekursiv vergleichen

    Die Möglich­keiten des Verzeichnis­vergleichs hängen ansonsten wesentlich von den Fähigkeiten des Cmdlets Get-ChildItem ab. Dieses erlaubt etwa auch die rekursive Anzeige von Dateien und Verzeichnissen, so dass man ganze Ordner­strukturen vergleichen kann:

    Compare (gci -r Docs) (gci -r Archiv)

    Dieser Befehl bewirkt einen Vergleich für ganze Verzeichnisbäume, bei dem es egal ist, wo innerhalb der Struktur die Dateien existieren. Gibt es gleichnamige Dateien etwa in .\Docs und in .\Archiv\old, dann stellt dieser Aufruf keinen Unterschied zwischen beiden Seiten fest. Der Grund dafür ist, dass gci nur eine lange Liste mit den reinen Dateinamen ohne Pfad liefert.

    Verzeichnisstruktur untersuchen

    Ein weiterer Filter ließe sich anwenden, wenn man etwa nur die leere Verzeichnis­struktur ohne Dateien vergleichen möchte:

    Compare (gci -r -Dir Docs) (gci -r -Dir Archiv)

    Der Schalter Dir (Alias für Directory) bewirkt, dass Get-ChildItem nur Verzeichnisse anzeigt. Wenn eines der beiden Verzeichnisse keine Unterver­zeichnisse hat, dann wirft Compare-Object einen Fehler aus. Das ist auch bei den anderen Beispielen der Fall, wenn die Ordner keine Dateien enthalten.

    Keine Kommentare