Clasificar directorios
Clasificación en función del número de archivos
El objetivo de este script es dividir un conjunto de directorios en dos bloques (directorios principales) en función de un criterio datos. En este caso concreto el criterio tiene que ver con la extensión de los archivos que contienen los directorios.
El contexto concreto en que surge este script es el análisis de los directorios expedientes SEO, en los se ha considerado pertinente diferenciar (en determinados subconjuntos) entre aquellos directorios que cuentan únicamente con determinado tipo de archivos (los llamados archivos-Procesador por derivar del uso de servicios de procesamiento de texto) del resto de los directorios que contienen al menos un archivo que no pertenece a esa categoría.
Para lo que ahora nos insteresa, lo relevante es que el script, además de realizar la identificación en función de ese criterio, debe generar un directorio y trasladar a él un determinado subconjunto de directorios.
Como en otras ocasiones, este script ha sido desarrollado con ayuda de Gemini-IA según procedimiento que se explica aquí (pendiente).
Paso a continuación a desarrollar el análisis del scritp, empezando por la identificación de las bibliotecas necesarias para su ejecución, que son las dos que se indican en el segmento de código que sigue.
#--- Bibliotecas necesarias ---------------------------
import os
import shutil
Ambas bibliotecas se usan para el trabajo con directorios y archivos, lo que indica que será ésta la acción que desarrolla la función que sigue y se analiza a continuación.
#--- Función --------------------------------------------------------------------------------
def clasificar_directorios(ruta_base):
# Definición de las extensiones de inclusión y de los identificadores de los grupos
ext_permitidas = {'.doc', '.docx', '.odt'}
nombre_p = "GRUPO_PROCESADOR"
nombre_o = "GRUPO_OTROS"
# Planteamiento de la estructura de directorios para contener los directorios categorizados
ruta_p = os.path.join(ruta_base, nombre_p)
ruta_o = os.path.join(ruta_base, nombre_o)
for d in [ruta_p, ruta_o]: # Crear contenedores
if not os.path.exists(d):
os.makedirs(d)
# Obtención de los directorios a evaluar según categorias
elementos = [f for f in os.listdir(ruta_base)
if os.path.isdir(os.path.join(ruta_base, f))
and f not in [nombre_p, nombre_o]]
print(f"--- Iniciando análisis en: {ruta_base} ---")
resumen = {nombre_p: 0, nombre_o: 0}
for carpeta in elementos:
ruta_carpeta = os.path.join(ruta_base, carpeta)
es_puro = True
tiene_contenido = False
archivo_intruso = None
for raiz, _, archivos in os.walk(ruta_carpeta): # Búsqueda en profundidad
for arc in archivos:
tiene_contenido = True
ext = os.path.splitext(arc)[1].lower()
if ext not in ext_permitidas:
es_puro = False
archivo_intruso = arc # Guardamos el nombre para el log
break
if not es_puro:
break
# Clasificación final. Si está vacío, no es "puro procesador", va a OTROS.
if es_puro and tiene_contenido:
destino_final = ruta_p
grupo_asignado = nombre_p
print(f"[ACEPTADO] {carpeta}: Todo es procesador.")
else:
destino_final = ruta_o
grupo_asignado = nombre_o
motivo = f"Intruso hallado: {archivo_intruso}" if tiene_contenido else "Carpeta vacía"
print(f"[RECHAZADO] {carpeta}: {motivo}. Enviado a OTROS.")
# Traslado del directorio (expedientes) al directorio de categorización
try:
shutil.move(ruta_carpeta, os.path.join(destino_final, carpeta))
resumen[grupo_asignado] += 1
except Exception as e:
print(f"[ERROR] No se pudo mover {carpeta}: {e}")
# Resumen final por pantalla ----------------------------------------------
print("\n" + "="*50)
print("RESUMEN DE DIRECTORIOS CREADOS")
print("-" * 50)
print(f"Detección de 'Sólo Procesador': {resumen[nombre_p]} carpetas.")
print(f"Detección de 'Otros/Mixtos': {resumen[nombre_o]} carpetas.")
print("="*50)
En esta función caben diferenciar dos partes muy dispares en extensión y peso en el procedimiento: los procesos que llevan a la identificación, catergorización y manipulación de los directorios y la información sobre los resultados que se muestra por pantalla. Evidentemente lo fundamental de la función pertenece a la primera parte, aunque es la segunda la que permite al usuario acceder a la información que le resulta relevante.
Como ya dije antes, en ese conjunto de procesos se diferencia, a su vez, varias fases, siendo la primera la identificación de los criterios de categorización, la segunda la creación de los directorios de categorización, la tercera la identificación del grupo de pertenencia de cada directorio-expediente (incluye la búsqueda en profundidad de los archivos cada directorio-expediente) y la cuarta el traslado del directorio al directorio de su grupo de pertenencia.
Como corresponde a esta estrucrtura de script, la tercera y última parte es el scritp de ejecución de la función, que contiene la asignación de contenido (identificación de la ruta de trabajo) ruta = r"Mi_Ruta" y la llamada a la función, incorporando el parámetro que requiere clasificar_directorios(ruta).
#--- Ejecución de la función -----------------------------------------
if __name__ == "__main__":
ruta = r"Mi_Ruta" # Sustituir por tu ruta deseada
clasificar_directorios(ruta) # Llamada a función
No hay comentarios:
Publicar un comentario
Comenta esta entrada