Revisa planes de renombrado de IA sin cambiar archivos
En esta página
Un asistente de IA puede convertir nombres de archivo poco claros en un plan útil. También puede proponer dos destinos idénticos o un nombre que sobrescriba un archivo existente. Pídele una propuesta, no un script con permiso para modificar tu carpeta.
Este tutorial crea un comprobador de Python de solo lectura para pequeños planes de renombrado en JSON. Funciona sin conexión en un sistema de archivos Linux que distingue mayúsculas y minúsculas; no necesitas una cuenta de IA ni paquetes adicionales. Los ejemplos son sintéticos, no resultados medidos de una IA.
1. Separa la propuesta de la ejecución
Proporciona al asistente un inventario de nombres aprobado y estas reglas:
- Devuelve solo una lista JSON de objetos con
sourceytarget. - Usa nombres simples, nunca rutas de directorios. Deben empezar por una letra o un dígito ASCII, contener solo letras y dígitos ASCII, puntos, guiones bajos o guiones, y tener como máximo 100 caracteres.
- Cada origen debe ser un archivo regular existente, no un enlace simbólico. Usa cada origen y destino una sola vez.
- Nunca elijas un nombre ocupado como destino, aunque otra fila proponga mover ese archivo.
Esto excluye deliberadamente intercambios, cadenas de renombrado, archivos ocultos y nombres con espacios. No envíes nombres privados a servicios no autorizados. Si cambias la regla de nombres, añade primero pruebas de aceptación de regex.
No pruebes un bucle de renombrado escrito por IA con los originales. En Unix, Path.rename() puede sobrescribir un archivo existente si los permisos lo permiten. Python documenta este comportamiento dependiente de la plataforma.
2. Guarda el comprobador de solo lectura
Guarda lo siguiente como audit_renames.py en un directorio de trabajo nuevo. Usa Python 3.10 o posterior. Valida el plan completo antes de mostrar la vista previa y no contiene ninguna operación de renombrado o escritura.
import json
from pathlib import Path
import re
import sys
NAME = re.compile(r"[A-Za-z0-9][A-Za-z0-9._-]{0,99}")
def audit(root, plan_path):
with open(plan_path, encoding="utf-8") as stream:
plan = json.load(stream)
if not isinstance(plan, list) or not plan:
raise ValueError("plan must be a nonempty list")
occupied = {entry.name for entry in root.iterdir()}
sources, targets = set(), set()
for row in plan:
if not isinstance(row, dict) or set(row) != {"source", "target"}:
raise ValueError("each row needs only source and target")
source, target = row["source"], row["target"]
if any(not isinstance(n, str) or not NAME.fullmatch(n)
for n in (source, target)):
raise ValueError("names must be simple ASCII basenames")
original = root / source
if original.is_symlink() or not original.is_file():
raise ValueError(f"not a regular source file: {source}")
if source in sources:
raise ValueError(f"repeated source: {source}")
if target in occupied:
raise ValueError(f"target already exists: {target}")
if target in targets:
raise ValueError(f"duplicate target: {target}")
sources.add(source)
targets.add(target)
return plan
if __name__ == "__main__":
if len(sys.argv) != 3:
raise SystemExit("Usage: python3 audit_renames.py DIRECTORY PLAN.json")
try:
plan = audit(Path(sys.argv[1]), sys.argv[2])
except (OSError, ValueError) as error:
raise SystemExit(f"FAIL: {error}")
for row in plan:
print(f"PREVIEW {row['source']} -> {row['target']}")
print(f"PASS: {len(plan)} planned renames; no files changed")
El decodificador JSON de la biblioteca estándar lee datos, no código Python ejecutable. Analizar el JSON no impone por sí solo nuestras reglas sobre nombres y colisiones; el bucle añade esas comprobaciones.
3. Crea un conjunto de prueba desechable
Guarda lo siguiente como make_fixture.py, junto al comprobador. Ejecútalo solo en el directorio de trabajo nuevo: crea tres archivos de texto, un enlace simbólico local y siete planes. Los planes comprueban deliberadamente distintos resultados.
import json
from pathlib import Path
root = Path("rename-demo")
root.mkdir()
for name in ("report-01.txt", "report-02.txt", "archive.txt"):
(root / name).write_text(name + "\n", encoding="utf-8")
(root / "shortcut.txt").symlink_to("report-01.txt")
def row(source, target):
return {"source": source, "target": target}
plans = {
"good": [row("report-01.txt", "notes-01.txt"),
row("report-02.txt", "notes-02.txt")],
"collision": [row("report-01.txt", "notes.txt"),
row("report-02.txt", "notes.txt")],
"occupied": [row("report-01.txt", "archive.txt")],
"escape": [row("report-01.txt", "../notes.txt")],
"missing": [row("report-99.txt", "notes.txt")],
"repeated": [row("report-01.txt", "notes-01.txt"),
row("report-01.txt", "notes-02.txt")],
"symlink": [row("shortcut.txt", "notes.txt")],
}
for name, plan in plans.items():
Path(name + ".json").write_text(json.dumps(plan), encoding="utf-8")
El generador de pruebas se niega a reutilizar un directorio rename-demo existente. No necesita tus documentos reales ni una respuesta generada por IA.
4. Ejecuta comprobaciones positivas y negativas
En Bash, ejecuta:
python3 make_fixture.py
for plan in good collision occupied escape missing repeated symlink; do
python3 audit_renames.py rename-demo "$plan.json"
echo "exit=$?"
done
No actives set -e en esta demostración: los seis fallos son intencionales. El plan correcto muestra:
PREVIEW report-01.txt -> notes-01.txt
PREVIEW report-02.txt -> notes-02.txt
PASS: 2 planned renames; no files changed
Resultados verificados localmente con Python 3.11.4:
| Plan | Resultado | Código de salida |
|---|---|---|
good |
Las tres líneas de stdout anteriores; stderr vacío | 0 |
collision |
FAIL: duplicate target: notes.txt |
1 |
occupied |
FAIL: target already exists: archive.txt |
1 |
escape |
FAIL: names must be simple ASCII basenames |
1 |
missing |
FAIL: not a regular source file: report-99.txt |
1 |
repeated |
FAIL: repeated source: report-01.txt |
1 |
symlink |
FAIL: not a regular source file: shortcut.txt |
1 |
Todos los fallos se escriben en stderr y dejan stdout vacío. El bucle de Bash muestra cada código de salida por separado. Los nombres, contenidos y destino del enlace permanecieron intactos tras las siete ejecuciones. Como al probar SQL escrito por IA, los fallos deliberados comprueban que el validador realmente rechaza errores.
5. Resuelve problemas y respeta los límites
- JSON no válido: elimina los delimitadores Markdown y los comentarios. No ejecutes la respuesta para repararla.
- Destino ocupado o duplicado: pide otro destino. Nunca evites la comprobación borrando el archivo existente.
- Origen ausente: actualiza el inventario en lugar de adivinar qué documento se pretendía usar.
- Se rechazan espacios o letras acentuadas: es una regla limitada del tutorial, no una restricción del sistema de archivos. Amplía explícitamente la política y las pruebas.
Superar las pruebas significa que la propuesta cumple estas comprobaciones, no que los nombres describan correctamente los documentos. Revisa tú el significado y las extensiones. El inventario es una vista momentánea, no un bloqueo del sistema de archivos; los cambios en el directorio pueden invalidarlo. La referencia de iteración de directorios de Python explica que no se especifica la inclusión de archivos añadidos o eliminados durante la iteración.
Esto no es una herramienta de renombrado para producción ni un detector de colisiones portable a Windows y volúmenes que ignoran las mayúsculas. Separa la ejecución, haz copias de seguridad y prueba cualquier ejecutor futuro con copias y sus propios controles para impedir sobrescrituras y recuperar el estado anterior.
Conclusión práctica
Deja que la IA proponga nombres mientras las comprobaciones deterministas rechazan planes defectuosos. Conserva el plan aceptado y su resultado, y añade cada nuevo fallo a tus casos de prueba continua. Una vista previa resulta útil precisamente porque no cambia nada.
Artículos relacionados
Evalúa la clasificación de incidencias con una matriz de confusión
Prueba expresiones regulares de IA con casos pequeños en Python
Evalúa transcripciones de IA con la tasa de error por palabra
Prueba el SQL generado por IA con pequeños juegos de datos de SQLite
Cómo evaluar la recuperación RAG con Recall@k y MRR
Qué Ofrece ChatGPT Enterprise y Cómo se Diferencia de Otros Planes
Cómo Pueden los Entrenadores de Fitness Usar ChatGPT para Entrenamientos Personalizados
ChatGPT Creó un Presupuesto que Funcionó—Pero Solo Hasta Cierto Punto
4 Maneras en que Usar ChatGPT Ahorra Tiempo y Aumenta la Productividad Cada Día
Por Qué el Duck Typing Hace que Python Sea Tan Poderoso
Dominando 7 Algoritmos Esenciales para Estructuras de Datos en Python
Guía para Principiantes para Elegir el Framework de Python Adecuado para tus Necesidades
Últimos artículos
Evalúa campos extraídos por IA con precisión y recall de coincidencia exacta
Comprueba las rutas propuestas por IA antes de escribir con Python
Evita actualizaciones de IA obsoletas con un control de versión en SQLite
Comprueba las dependencias de tareas de IA antes de programarlas con Python
Revisa los cambios JSON de la IA con una lista de campos permitidos
Combina resultados RAG con fusión de rangos recíprocos
Comprueba las horas de calendario de IA antes de crear eventos
Comprueba citas textuales de IA con fuentes locales y Python
Comprueba las cifras de resúmenes de IA con una tabla de referencia
Elige umbrales de revisión de IA con cobertura y tasas de error
Comprueba los marcadores de traducciones de IA con Python