Puedes automatizar tareas con archivos y carpetas en Python usando los módulos os y shutil, que vienen incluidos sin necesidad de instalar nada extra.
Estos dos módulos te permiten mover, renombrar, copiar y eliminar archivos desde tu script. Así eliminas el trabajo manual de organizar reportes, respaldos y descargas.
Los módulos os y shutil
os interactúa con el sistema operativo: crea carpetas, lista archivos y construye rutas.
shutil maneja operaciones de alto nivel: copia, mueve y elimina archivos o carpetas completas.
Ambos módulos se importan al inicio de tu script:
import os
import shutil
No necesitas pip install. Python los incluye por defecto.
Estructura general de un script de archivos
Todo script de automatización de archivos sigue esta estructura:
1. Importaciones → os, shutil, otros módulos
2. Configuración → rutas base, extensiones, prefijos
3. Lógica → recorrer archivos, aplicar operaciones
4. Punto de entrada → if __name__ == "__main__"
Esta estructura es la misma que aprendiste en la lección anterior. La consistencia en tu código facilita el mantenimiento.
Operaciones básicas con ejemplos
Crear y verificar carpetas
Usa os.makedirs() para crear una carpeta. El parámetro exist_ok=True evita errores si ya existe.
import os
carpeta = "reportes/enero"
os.makedirs(carpeta, exist_ok=True)
print(f"Carpeta lista: {carpeta}")
Salida:
Carpeta lista: reportes/enero
Listar archivos en una carpeta
os.listdir() devuelve una lista con los nombres de todos los elementos en una ruta.
import os
archivos = os.listdir("reportes")
for archivo in archivos:
print(archivo)
Para filtrar solo archivos .xlsx, combina con endswith():
for archivo in os.listdir("reportes"):
if archivo.endswith(".xlsx"):
print(f"Reporte encontrado: {archivo}")
Ejemplo 1 — Organizar reportes de ventas de FEMSA
Imagina que el equipo de FEMSA genera reportes diarios con nombres como ventas_2024_03_01.xlsx. Tu tarea: moverlos automáticamente a carpetas por mes.
import os
import shutil
ORIGEN = "descargas"
DESTINO_BASE = "reportes_organizados"
def organizar_reportes():
for archivo in os.listdir(ORIGEN):
if archivo.startswith("ventas_") and archivo.endswith(".xlsx"):
# Extraer mes del nombre: ventas_2024_03_01.xlsx
partes = archivo.replace(".xlsx", "").split("_")
mes = partes[2] # "03"
carpeta_mes = os.path.join(DESTINO_BASE, f"mes_{mes}")
os.makedirs(carpeta_mes, exist_ok=True)
origen_ruta = os.path.join(ORIGEN, archivo)
destino_ruta = os.path.join(carpeta_mes, archivo)
shutil.move(origen_ruta, destino_ruta)
print(f"Movido: {archivo} → mes_{mes}")
if __name__ == "__main__":
organizar_reportes()
Salida:
Movido: ventas_2024_03_01.xlsx → mes_03
Movido: ventas_2024_03_15.xlsx → mes_03
Movido: ventas_2024_04_02.xlsx → mes_04
shutil.move() mueve el archivo al destino. Si el destino está en otra unidad, copia y luego elimina el original.
Ejemplo 2 — Crear respaldos automáticos para Liverpool
El equipo de TI de Liverpool necesita copiar archivos críticos a una carpeta de respaldo antes de procesarlos.
import os
import shutil
from datetime import date
ORIGEN = "datos_produccion"
RESPALDO_BASE = "respaldos"
def crear_respaldo():
hoy = date.today().strftime("%Y-%m-%d")
carpeta_respaldo = os.path.join(RESPALDO_BASE, hoy)
os.makedirs(carpeta_respaldo, exist_ok=True)
copiados = 0
for archivo in os.listdir(ORIGEN):
ruta_origen = os.path.join(ORIGEN, archivo)
if os.path.isfile(ruta_origen): # Solo archivos, no subcarpetas
shutil.copy2(ruta_origen, carpeta_respaldo)
copiados += 1
print(f"Respaldo completado: {copiados} archivos copiados en {carpeta_respaldo}")
if __name__ == "__main__":
crear_respaldo()
Salida:
Respaldo completado: 14 archivos copiados en respaldos/2024-04-10
shutil.copy2() copia el archivo y conserva los metadatos originales (fecha de modificación, permisos). Úsalo cuando necesites un respaldo fiel.
Ejemplo 3 — Renombrar archivos en lote para Bimbo
El equipo de Bimbo recibe facturas con nombres inconsistentes. Necesitas agregarles el prefijo BIMBO_ y convertir el nombre a mayúsculas.
import os
CARPETA = "facturas_pendientes"
def renombrar_facturas():
for archivo in os.listdir(CARPETA):
if archivo.endswith(".pdf"):
nombre_nuevo = "BIMBO_" + archivo.upper()
ruta_original = os.path.join(CARPETA, archivo)
ruta_nueva = os.path.join(CARPETA, nombre_nuevo)
os.rename(ruta_original, ruta_nueva)
print(f"Renombrado: {archivo} → {nombre_nuevo}")
if __name__ == "__main__":
renombrar_facturas()
Salida:
Renombrado: factura_001.pdf → BIMBO_FACTURA_001.PDF
Renombrado: factura_002.pdf → BIMBO_FACTURA_002.PDF
os.rename() renombra dentro de la misma unidad de disco. Si necesitas mover y renombrar al mismo tiempo, usa shutil.move() con la ruta de destino completa incluyendo el nuevo nombre.
Eliminar archivos y carpetas con precaución
Eliminar archivos es permanente. No van a la papelera de reciclaje.
| Operación | Función | Descripción |
|---|---|---|
| Eliminar un archivo | os.remove(ruta) |
Borra el archivo indicado |
| Eliminar carpeta vacía | os.rmdir(ruta) |
Solo funciona si la carpeta está vacía |
| Eliminar carpeta con contenido | shutil.rmtree(ruta) |
Borra carpeta y todo su contenido |
Usa siempre una verificación antes de eliminar:
import os
archivo = "temp/reporte_borrador.xlsx"
if os.path.exists(archivo):
os.remove(archivo)
print(f"Archivo eliminado: {archivo}")
else:
print(f"Archivo no encontrado: {archivo}")
Referencia rápida: funciones esenciales
| Función | Módulo | Uso |
|---|---|---|
os.makedirs(ruta, exist_ok=True) |
os |
Crear carpeta (y subcarpetas) |
os.listdir(ruta) |
os |
Listar contenido de una carpeta |
os.path.join(a, b) |
os |
Construir rutas compatibles con el OS |
os.path.exists(ruta) |
os |
Verificar si existe un archivo o carpeta |
os.path.isfile(ruta) |
os |
Confirmar que es un archivo (no carpeta) |
os.rename(origen, destino) |
os |
Renombrar archivo en el mismo directorio |
os.remove(ruta) |
os |
Eliminar un archivo |
shutil.copy2(origen, destino) |
shutil |
Copiar archivo conservando metadatos |
shutil.move(origen, destino) |
shutil |
Mover o renombrar (entre unidades también) |
shutil.rmtree(ruta) |
shutil |
Eliminar carpeta y todo su contenido |
Errores comunes
Error 1 — Rutas con barras incorrectas en Windows
Escribir rutas manualmente con \ causa errores en Windows porque Python interpreta \n como salto de línea.
# ❌ Incorrecto
ruta = "C:\reportes\nuevos"
# ✅ Correcto
ruta = os.path.join("C:", "reportes", "nuevos")
Siempre usa os.path.join() para construir rutas. Funciona igual en Windows, Mac y Linux.
Error 2 — Usar shutil.rmtree() sin verificar la ruta
shutil.rmtree() elimina todo sin preguntar. Un error tipográfico en la ruta puede borrar carpetas críticas.
# ❌ Peligroso sin validación
shutil.rmtree(carpeta_temp)
# ✅ Con validación
if os.path.exists(carpeta_temp) and "temp" in carpeta_temp:
shutil.rmtree(carpeta_temp)
Agrega una condición que confirme que la ruta contiene una palabra clave como "temp" o "borrador".
Error 3 — Confundir shutil.copy() con shutil.copy2()
shutil.copy() copia el archivo pero no conserva la fecha de modificación original. Para respaldos, usa siempre shutil.copy2(). La diferencia importa cuando necesitas auditar cuándo se creó un archivo.
Error 4 — No usar os.path.isfile() al recorrer carpetas
os.listdir() devuelve tanto archivos como subcarpetas. Si aplicas shutil.copy2() sobre una subcarpeta, obtendrás un error.
for elemento in os.listdir(ORIGEN):
ruta = os.path.join(ORIGEN, elemento)
if os.path.isfile(ruta): # Filtra solo archivos
shutil.copy2(ruta, DESTINO)