Datei- und Verzeichnisvergleiche mit Python

07 Jan 2019

Die Python-Standardbibliothek bietet sofort einsatzbereite leistungsstarke Tools, einschließlich der Handhabung des Dateisystems. In diesem kurzen Artikel finden Sie einige nützliche Rezepte zum Vergleichen von Dateien und Verzeichnissen mit dem filecmp-Modul.

Wenn Sie ein schmerzhaftes Durcheinander von Dateien und Ordnern haben (wie hier oder hier), die schwer zu durchforsten sind, ist Python Ihr Freund, um die Suche und den Vergleich zu automatisieren. Dies kann dann mit der automatischen Verarbeitung, Änderung oder Löschung von Dateien und Verzeichnissen kombiniert werden, anstatt jede Datei manuell durchzugehen.

Eine faire Warnung: Überprüfen und testen Sie den Code immer ordnungsgemäß, wenn Sie das Dateisystem mit einer Operation wie Löschen, Umbenennen, Kopieren usw. ändern. Und halten Sie auch mehrere Kopien Ihrer wichtigen Dateien „Zwei ist eins und eins ist keine“.

Im Modul filecmp finden Sie die Funktion cmp(), mit der zwei Dateien verglichen werden können. Standardmäßig ist der Vergleich flach (shallow=True ), was bedeutet, dass nur das Betriebssystem.stat() -Signaturen (wie Größe, Änderungsdatum, …) beider Dateien werden verglichen. Durch Setzen von shallow=False erfolgt der Vergleich, indem der Inhalt der Dateien verglichen wird, was mehr Zeit in Anspruch nimmt. Hier ist ein Snippet, mit dem Sie alle Duplikate in einem Ordner finden können:

import osimport itertoolsimport filecmpfiles = os.listdir('path/to/directory')for f1, f2 in itertools.combinations(files, 2): if filecmp.cmp(f1, f2): print(f1, f2)

Hier sehen Sie die Verwendung eines weiteren sehr nützlichen Moduls aus der Python-Standardbibliothek, des Itertools-Moduls, das Ihnen bei verschiedenen Iteratoren und Schleifenfunktionen helfen kann. In diesem Fall sehen Sie die Funktion combinations(), die alle Permutationen der Länge 2 der Liste der Dateien zurückgibt. Dadurch wird sichergestellt, dass jede Datei mit jeder anderen Datei in der Liste verglichen wird. Um alle Dateien in einem Ordner rekursiv zu durchsuchen, ersetzen Sie files = os.listdir('...') im vorherigen Code durch:

files = for (dirpath, dirnames, filenames) in os.walk('.'): for f in filenames: files.append(os.path.join(dirpath, f))

Sie können Verzeichnisse auch mit der dircmp-Klasse vergleichen. Das folgende Snippet durchläuft zwei Ordner rekursiv und zeigt alle Dateien an, die denselben Namen haben, aber unterschiedlich sind, und listet alle Dateien auf, die entweder im linken oder rechten Dateipfad vorhanden sind:

import filecmpc = filecmp.dircmp(filepath1, filepath2)def report_recursive(dcmp): for name in dcmp.diff_files: print("DIFF file %s found in %s and %s" % (name, dcmp.left, dcmp.right)) for name in dcmp.left_only: print("ONLY LEFT file %s found in %s" % (name, dcmp.left)) for name in dcmp.right_only: print("ONLY RIGHT file %s found in %s" % (name, dcmp.right)) for sub_dcmp in dcmp.subdirs.values(): print_diff_files(sub_dcmp)report_recursive(c)

Dies ist eine großartige Möglichkeit, wenn Sie mehrere Ordner mit demselben Namen haben, aber keine Ahnung haben, ob sie denselben Inhalt haben (wie verschiedene Versionen eines Sicherungsordners). Denken Sie daran, dass dies nur einen flachen Vergleich durchführt, wie Sie es im vorherigen Dateivergleich gesehen haben.