porównywanie plików i katalogów z Pythonem

07 sty 2019

standardowa biblioteka Pythona oferuje potężny zestaw narzędzi, w tym obsługę systemu plików. W tym krótkim artykule zobaczysz kilka przydatnych przepisów do porównywania plików i katalogów z modułem filecmp.

kiedy masz bolesny bałagan plików i folderów (jak tutaj lub tutaj), które są trudne do przebrnięcia, Python jest twoim przyjacielem, aby zautomatyzować wyszukiwanie i porównywanie. Można to następnie połączyć z automatycznym przetwarzaniem, modyfikacją lub usuwaniem plików i katalogów zamiast ręcznego przeglądania KAŻDEGO pliku.

uczciwe ostrzeżenie: zawsze sprawdzaj i testuj kod poprawnie podczas modyfikowania systemu plików za pomocą dowolnej operacji, takiej jak usuwanie, zmiana nazwy, kopiowanie, między innymi. A także przechowywać wiele kopii ważnych plików „dwa to jeden, a jeden to żaden”.

w module filecmp znajdziesz funkcję cmp(), która może porównywać dwa pliki. Domyślnie porównanie jest płytkie (shallow=True) co oznacza, że tylko os.sygnatury stat () (takie jak rozmiar, Data modyfikacji,…) obu plików są porównywane. Po ustawieniu shallow=False porównanie odbywa się poprzez porównanie zawartości plików, co zajmuje więcej czasu. Oto fragment, którego możesz użyć, aby znaleźć wszystkie duplikaty w folderze:

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)

tutaj możesz zobaczyć użycie innego bardzo użytecznego modułu z biblioteki standardowej Pythona, modułu itertools, który może pomóc w różnych iteratorach i funkcjach pętli. W tym przypadku można zobaczyć funkcję combinations (), która zwraca wszystkie permutacje o długości 2 listy plików. Dzięki temu każdy plik jest porównywany z każdym innym plikiem na liście. Aby przeszukiwać rekurencyjnie wszystkie pliki w folderze, zamień files = os.listdir('...') w poprzednim kodzie na:

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

możesz także porównać katalogi z klasą dircmp. Poniższy fragment przechodzi rekurencyjnie przez dwa foldery i wyświetla wszystkie pliki, które mają tę samą nazwę, ale są różne i wyświetla wszystkie pliki, które istnieją po lewej lub prawej ścieżce pliku:

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)

jest to świetny sposób, jeśli masz wiele folderów o tej samej nazwie, ale nie masz pojęcia, czy mają tę samą zawartość (jak różne wersje folderu kopii zapasowej). Należy pamiętać, że robi to tylko płytkie porównanie, jak widziałeś w porównaniu plików przed.