Comparaciones de archivos y directorios con Python
07 De enero de 2019
La biblioteca estándar de Python ofrece un potente conjunto de herramientas listas para usar, incluido el manejo del sistema de archivos. En este breve artículo, verá un par de recetas útiles para comparar archivos y directorios con el módulo filecmp.
Cuando tienes un lío doloroso de archivos y carpetas (como aquí o aquí), que son difíciles de atravesar, Python es tu amigo para automatizar la búsqueda y comparación. Esto se puede combinar con el procesamiento automático, la modificación o la eliminación de archivos y directorios en lugar de revisar manualmente cada archivo.
Una advertencia justa: Siempre verifique y pruebe el código correctamente al modificar el sistema de archivos con cualquier operación como borrar, cambiar el nombre, copiar, entre otras. Y también guarde varias copias de sus archivos importantes «Dos es Uno y Uno es Ninguno».
En el módulo filecmp
encontrará la función cmp()
que puede comparar dos archivos. De forma predeterminada, la comparación es superficial (shallow=True
), lo que significa que solo el sistema operativo.se comparan las firmas stat () (como el tamaño, la fecha de modificación, both) de ambos archivos. Al establecer shallow=False
, la comparación se realiza comparando el contenido de los archivos, lo que lleva más tiempo. Aquí hay un fragmento de código que puede usar para encontrar todos los duplicados en una carpeta:
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)
Aquí puede ver el uso de otro módulo muy útil de la biblioteca estándar de Python, el módulo itertools, que puede ayudarlo con varios iteradores y funciones de bucle. En este caso se puede ver la función combinations() que devuelve todas las permutaciones de longitud 2 de la lista de archivos. Esto asegura que cada archivo se compare entre sí en la lista. Para buscar recursivamente en todos los archivos de una carpeta, reemplace files = os.listdir('...')
en el código anterior con:
files = for (dirpath, dirnames, filenames) in os.walk('.'): for f in filenames: files.append(os.path.join(dirpath, f))
También puede comparar directorios con la clase dircmp. El siguiente fragmento recorre dos carpetas recursivamente y muestra todos los archivos que tienen el mismo nombre, pero son diferentes, y enumera todos los archivos que existen en la ruta de archivo izquierda o derecha:
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)
Esta es una excelente manera si tiene varias carpetas con el mismo nombre, pero no tiene idea de si tienen el mismo contenido (como diferentes versiones de una carpeta de copia de seguridad). Tenga en cuenta que esto solo hace una comparación superficial como vio en la comparación de archivos anterior.