Confronti di file e directory con Python
07 Jan 2019
La libreria standard Python offre un potente set di strumenti pronti all’uso, inclusa la gestione del file system. In questo breve articolo vedrete un paio di ricette utili per confrontare i file e le directory con il modulo filecmp.
Quando si dispone di un pasticcio doloroso di file e cartelle (come qui, o qui), che sono difficili da arare attraverso, Python è tuo amico per automatizzare la ricerca e il confronto. Questo può quindi essere combinato con l’elaborazione automatica, la modifica o la cancellazione di file e directory invece di passare manualmente attraverso ogni file.
Un giusto avvertimento: controllare e testare sempre il codice correttamente quando si modifica il file system con qualsiasi operazione come l’eliminazione, la ridenominazione, la copia, tra gli altri. E anche mantenere più copie dei file importanti “Due è uno e uno è nessuno”.
Nel modulo filecmp
troverai la funzione cmp()
che può confrontare due file. Per impostazione predefinita, il confronto è superficiale (shallow=True
), il che significa che solo il sistema operativo.le firme stat () (come dimensione, data di modifica,…) di entrambi i file vengono confrontate. Impostando shallow=False
il confronto viene eseguito confrontando il contenuto dei file, il che richiede più tempo. Ecco un frammento che puoi usare per trovare tutti i duplicati in una cartella:
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)
Qui puoi vedere l’uso di un altro modulo molto utile dalla libreria standard Python, il modulo itertools, che può aiutarti con vari iteratori e funzioni di loop. In questo caso puoi vedere la funzione combinations() che restituisce tutte le permutazioni di lunghezza 2 dell’elenco dei file. Questo fa in modo che ogni file viene confrontato con ogni altro file nella lista. Per cercare ricorsivamente su tutti i file in una cartella, sostituire files = os.listdir('...')
nel codice precedente con:
files = for (dirpath, dirnames, filenames) in os.walk('.'): for f in filenames: files.append(os.path.join(dirpath, f))
È inoltre possibile confrontare le directory con la classe dircmp. Lo snippet seguente passa attraverso due cartelle in modo ricorsivo e visualizza tutti i file che hanno lo stesso nome, ma sono diversi ed elenca tutti i file che esistono sul filepath sinistro o destro:
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)
Questo è un ottimo modo se hai più cartelle con lo stesso nome ma non hai idea se hanno lo stesso contenuto (come diverse versioni di una cartella di backup). Tieni presente che questo fa solo un confronto superficiale come hai visto nel confronto dei file prima.