Comparaisons de fichiers et de répertoires avec Python

07 Jan 2019

La bibliothèque standard Python offre un ensemble puissant d’outils prêts à l’emploi, y compris la gestion du système de fichiers. Dans ce petit article rapide, vous verrez quelques recettes utiles pour comparer des fichiers et des répertoires avec le module filecmp.

Lorsque vous avez un gâchis douloureux de fichiers et de dossiers (comme ici, ou ici), difficiles à parcourir, Python est votre ami pour automatiser la recherche et la comparaison. Cela peut ensuite être combiné avec un traitement automatique, une modification ou une suppression de fichiers et de répertoires au lieu de parcourir manuellement chaque fichier.

Un avertissement juste: Vérifiez et testez toujours correctement le code lors de la modification du système de fichiers avec toute opération comme la suppression, le renommage, la copie, entre autres. Et conservez également plusieurs copies de vos fichiers importants « Deux est Un et Un n’est Aucun ».

Dans le module filecmp vous trouverez la fonction cmp() qui permet de comparer deux fichiers. Par défaut, la comparaison est superficielle (shallow=True), ce qui signifie que seul le système d’exploitation.les signatures stat() (comme la taille, la date de modification, …) des deux fichiers sont comparées. En définissant shallow=False, la comparaison se fait en comparant le contenu des fichiers, ce qui prend plus de temps. Voici un extrait que vous pouvez utiliser pour trouver tous les doublons dans un dossier:

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)

Ici, vous pouvez voir l’utilisation d’un autre module très utile de la bibliothèque standard Python, le module itertools, qui peut vous aider avec divers itérateurs et fonctions de boucle. Dans ce cas, vous pouvez voir la fonction combinations() qui renvoie toutes les permutations de longueur 2 de la liste des fichiers. Cela garantit que chaque fichier est comparé les uns aux autres dans la liste. Pour effectuer une recherche récursive sur tous les fichiers d’un dossier, remplacez files = os.listdir('...') dans le code précédent par:

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

Vous pouvez également comparer les répertoires avec la classe dircmp. L’extrait de code suivant parcourt récursivement deux dossiers et affiche tous les fichiers qui ont le même nom, mais qui sont différents et répertorie tous les fichiers qui existent sur le chemin de fichier gauche ou droit:

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)

C’est un excellent moyen si vous avez plusieurs dossiers avec le même nom mais que vous ne savez pas s’ils ont le même contenu (comme différentes versions d’un dossier de sauvegarde). Gardez à l’esprit que cela ne fait qu’une comparaison superficielle comme vous l’avez vu dans la comparaison de fichiers auparavant.