En este artículo, usaremos un concepto llamado hash para identificar archivos únicos y eliminar archivos duplicados usando Python.
Módulos requeridos:
- tkinter: Necesitamos hacer una manera para que podamos seleccionar la carpeta en la que queremos hacer este proceso de limpieza para que cada vez que ejecutemos el código obtengamos un diálogo de archivo para seleccionar una carpeta y vamos a usar la biblioteca Tkinter. En esta biblioteca, tenemos un método llamado «askdirectory» que se puede usar para pedirle al usuario que elija un directorio. Para instalar esta biblioteca, escriba el siguiente comando en IDE/terminal.
pip install tk
- hashlib: para usar la función hash md5 necesitamos la biblioteca hashlib. Para instalar esta biblioteca, escriba el siguiente comando en IDE/terminal.
pip install hashlib
- os: este módulo nos ayuda a eliminar archivos duplicados al proporcionar funciones para recuperar el contenido de los archivos y eliminarlos, etc. Para instalar esta biblioteca, escriba el siguiente comando en IDE/terminal. El módulo os es parte de la biblioteca estándar dentro de Python.
Acercarse:
- Le pediremos al usuario que seleccione una carpeta y buscaremos en este directorio general todos los archivos duplicados y redundantes.
- Tomaremos el contenido de cada archivo y lo pasaremos a través de una función hash que generará una string única correspondiente a un archivo único.
- La string hash tendrá un tamaño fijo y el tamaño dependerá del tipo de función hash que estemos usando. Tenemos muchas funciones hash como md5, SHA1 o SHA 256, y muchas otras. En este artículo, usaremos el hash md5 y siempre producirá un valor hash de 32 caracteres, independientemente del tamaño y el tipo del archivo.
- Para detectar archivos duplicados y luego eliminar esos archivos, vamos a mantener un diccionario de python.
- Vamos a pasar la string hash de todos y cada uno de los archivos dentro de cada subcarpeta del directorio raíz como claves de diccionario y rutas de archivos como valores del diccionario.
- Cada vez que insertamos un nuevo registro de archivo, comprobaremos si estamos obteniendo entradas duplicadas en nuestro diccionario. Si encontramos algún archivo duplicado, tomaremos la ruta del archivo y lo eliminaremos.
Implementación paso a paso
Paso 1: importa las bibliotecas Tkinter, os, hashlib y pathlib.
Python3
from tkinter.filedialog import askdirectory from tkinter import Tk import os import hashlib from pathlib import Path
Paso 2: estamos usando tk.withdraw porque no queremos que aparezca la ventana GUI de tkinter en nuestra pantalla, solo queremos el cuadro de diálogo de archivo para seleccionar la carpeta. askdirectory(title=”Seleccionar una carpeta”) esta línea de código abre un cuadro de diálogo en la pantalla a través del cual podemos seleccionar una carpeta.
Python3
Tk().withdraw() file_path = askdirectory(title="Select a folder")
Paso 3: A continuación, debemos enumerar todos los archivos dentro de nuestra carpeta raíz. Para hacer eso, necesitamos el módulo del sistema operativo, os.walk() toma la ruta de nuestra carpeta raíz como argumento y recorrerá cada subdirectorio de la carpeta que se le ha asignado y mostrará una lista de todos los archivos. Esta función devuelve una lista de tuplas con tres elementos. El primer elemento es la ruta a esa carpeta y el segundo elemento son todas las subcarpetas dentro de esa carpeta y el tercer elemento es una lista de todos los archivos dentro de esa carpeta.
Python3
list_of_files = os.walk(file_path)
Paso 4: Nuestro objetivo final es enumerar todos los archivos en todos y cada uno de los subdirectorios y el directorio principal, por eso estamos ejecutando un bucle for en todos los archivos. Necesitamos abrir todos y cada uno de los archivos y convertirlos en una string hash para hacer eso, definiremos una variable llamada hash_file. La función hash md5 convertirá todo el contenido de nuestro archivo en hash md5. Para abrir un archivo, primero debemos tener la ruta, así que aquí estamos usando otra función en el módulo os llamada os.path.join(). Entonces diremos que abra el archivo usando la ruta del archivo en modo de lectura. Esto convertirá nuestro archivo en un hash md5. Para obtener la string hash vamos a utilizar el método hexdigest().
Python3
for root, folders, files in list_of_files: for file in files: file_path = Path(os.path.join(root, file)) Hash_file = hashlib.md5(open( file_path,'rb').read()).hexdigest()
Paso 5: Para detectar los archivos duplicados vamos a definir un diccionario vacío. Agregaremos elementos a este diccionario y la clave de cada elemento será el hash del archivo y el valor será la ruta del archivo. Si el hash del archivo ya se ha agregado a este diccionario de archivos únicos, eso significa que hemos encontrado un archivo duplicado y necesitamos eliminar ese archivo, por lo que simplemente lo eliminaremos usando la función os.remove() . Si no está allí, lo agregaremos a ese diccionario.
Python3
unique_files = dict() if Hash_file not in unique_files: unique_files[Hash_file] = file_path else: os.remove(file_path) print(f"{file_path} has been deleted")
A continuación se muestra la implementación completa:
Python3
from tkinter.filedialog import askdirectory # Importing required libraries. from tkinter import Tk import os import hashlib from pathlib import Path # We don't want the GUI window of # tkinter to be appearing on our screen Tk().withdraw() # Dialog box for selecting a folder. file_path = askdirectory(title="Select a folder") # Listing out all the files # inside our root folder. list_of_files = os.walk(file_path) # In order to detect the duplicate # files we are going to define an empty dictionary. unique_files = dict() for root, folders, files in list_of_files: # Running a for loop on all the files for file in files: # Finding complete file path file_path = Path(os.path.join(root, file)) # Converting all the content of # our file into md5 hash. Hash_file = hashlib.md5(open(file_path, 'rb').read()).hexdigest() # If file hash has already # # been added we'll simply delete that file if Hash_file not in unique_files: unique_files[Hash_file] = file_path else: os.remove(file_path) print(f"{file_path} has been deleted")
Producción:
Publicación traducida automáticamente
Artículo escrito por vinayedula y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA