Basiert auf der aktuell akzeptierten Antwort von @Mateusz Kobos, stellt sich heraus, dass das zweite filecmp.cmpfiles
mit shallow=False
nicht notwendig ist, daher haben wir es entfernt. Man kann dirs_cmp.diff_files
aus dem ersten dircmp
erhalten. Ein häufiges Missverständnis (das auch wir hatten!) ist, dass dir_cmp
nur oberflächlich ist und nicht die Dateiinhalte vergleicht! Es stellt sich heraus, dass das nicht stimmt! Die Bedeutung von shallow=True
besteht nur darin, Zeit zu sparen und behandelt zwei Dateien mit unterschiedlichen letzten Änderungszeiten tatsächlich nicht als unterschiedlich. Wenn die letzte Änderungszeit zwischen zwei Dateien unterschiedlich ist, wird der Inhalt jeder Datei gelesen und deren Inhalt verglichen. Wenn die Inhalte identisch sind, ist es ein Treffer, auch wenn das letzte Änderungsdatum unterschiedlich ist! Wir haben hier detaillierte Ausgaben hinzugefügt, um mehr Klarheit zu schaffen. Sehen Sie sich anderswo (filecmp.cmp() ignoriert unterschiedliche os.stat()-Signaturen?) an, wenn Sie Unterschiede in st_modtime
als Nichtübereinstimmung betrachten möchten. Wir haben auch auf die neuere pathlib- statt der os-Bibliothek umgestellt.
import filecmp
from pathlib import Path
def compare_directories_recursive(dir1:Path, dir2:Path,verbose=True):
"""
Vergleicht zwei Verzeichnisse rekursiv.
Zuerst werden die Dateizahlen in jedem Verzeichnis verglichen.
Zweitens werden Dateien als gleich angesehen, wenn ihre Namen, Größe und letztes Änderungsdatum gleich sind (auch bekannt als shallow=True in Python).
Wenn sich das letzte Änderungsdatum unterscheidet, werden die Inhalte durch Lesen jeder Datei verglichen.
Einschränkung: Wenn die Inhalte gleich sind und das letzte Änderungsdatum NICHT gleich ist, werden die Dateien immer noch als gleich betrachtet!
Diese Einschränkung ist das Standardverhalten von Python filecmp, so unlogisch es auch erscheinen mag.
@param dir1: Pfad zum ersten Verzeichnis
@param dir2: Pfad zum zweiten Verzeichnis
"""
dirs_cmp = filecmp.dircmp(str(dir1), str(dir2))
if len(dirs_cmp.left_only)>0:
if verbose:
print(f"Es sollten nicht mehr Dateien im Originalverzeichnis als im Zielverzeichnis (left_only) sein: {dirs_cmp.left_only}")
return False
if len(dirs_cmp.right_only)>0:
if verbose:
print(f"Es sollten nicht mehr Dateien im Zielverzeichnis als im Originalverzeichnis (right_only) sein: {dirs_cmp.right_only}")
return False
if len(dirs_cmp.funny_files)>0:
if verbose:
print(f"Es sollten keine lustigen Dateien zwischen Original und Ziel geben. Diese Datei(en) sind lustig: {dirs_cmp.funny_files}")
return False
if len(dirs_cmp.diff_files)>0:
if verbose:
print(f"Es sollten keine unterschiedlichen Dateien zwischen Original und Ziel geben. Diese Datei(en) sind unterschiedlich: {dirs_cmp.diff_files}")
return False
for common_dir in dirs_cmp.common_dirs:
new_dir1 = Path(dir1).joinpath(common_dir)
new_dir2 = Path(dir2).joinpath(common_dir)
if not compare_directories_recursive(new_dir1, new_dir2):
return False
return True
0 Stimmen
Was ist "AFIAC"? Kann es nicht in einem gängigen Akronym finden, wenn gesucht wird.
0 Stimmen
@LondonAppDev Meine Vermutung ist, dass der Autor AFAIC gemeint hat (so weit ich das beurteilen kann (z.B. oxfordlearnersdictionaries.com/us/definition/english/…)), aber es möglicherweise als AFIAC falsch geschrieben hat. Eng verwandt mit AFAIK, d.h. so weit ich weiß.