Renombrar-Espacios, script de PowerShell para eliminar espacios en nombres de archivos y carpetas de forma recursiva
![]()
Es habitual encontrarse con árboles de carpetas heredados de sistemas Windows, correos exportados o migraciones de datos donde los nombres de archivos y carpetas contienen espacios. Esto puede causar problemas al:
- Trabajar con rutas desde la línea de comandos o scripts (los espacios obligan a usar comillas y son una fuente frecuente de errores).
- Sincronizar o copiar archivos hacia servidores Linux, buckets de almacenamiento en la nube o repositorios Git.
- Generar URLs o enlaces directos a archivos, donde los espacios deben codificarse (
%20). - Automatizar procesos con herramientas de línea de comandos (rsync, curl, git, etc.) que tratan el espacio como separador de argumentos.
Renombrar-Espacios.ps1 es un script de PowerShell que recorre una carpeta de forma recursiva y sustituye todos los espacios de los nombres de archivos y subcarpetas por guiones bajos (_), dejando la estructura y el contenido intactos.
¿Qué problema resuelve?
Más allá del simple reemplazo de caracteres, el script está pensado para funcionar de forma segura en entornos reales de Windows, donde aparecen tres problemas típicos:
- Orden de renombrado. Si se renombra una carpeta antes que su contenido, las rutas de los archivos que aún faltan por procesar quedan invalidadas. El script procesa primero los elementos más profundos del árbol y termina por los más superficiales, evitando este problema.
- Rutas demasiado largas. Windows limita las rutas a 260 caracteres por defecto. Es habitual superar este límite con archivos como correos
.emlexportados, que incluyen asuntos largos y metadatos en el propio nombre. El script añade automáticamente el prefijo especial\\?\(o\\?\UNC\en rutas de red) para saltarse esa limitación. - Errores puntuales que detienen todo el proceso. Si un solo archivo falla (por permisos, bloqueo del archivo, etc.), un script básico se detendría por completo. Este script captura el error, lo muestra en pantalla y continúa con el resto de archivos y carpetas.
Requisitos
- Windows con PowerShell 5.1 o superior (viene preinstalado en Windows 10 y 11).
- Permisos de lectura y escritura sobre la carpeta a procesar.
- Si la carpeta está en una unidad de red mapeada (por ejemplo
Z:), la unidad debe estar conectada antes de ejecutar el script.
Instalación
No requiere instalación. Basta con descargar el archivo Renombrar-Espacios.ps1 y guardarlo en cualquier carpeta local.
Si es la primera vez que ejecutas scripts de PowerShell en el equipo, es posible que necesites habilitar su ejecución. Abre PowerShell y ejecuta una sola vez:
powershell
Set-ExecutionPolicy -Scope CurrentUser RemoteSignedEsto permite ejecutar scripts locales (como este) mientras sigue exigiendo firma digital para scripts descargados de internet.
Alternativa si no puedes ejecutar como administrador o la política de ejecución no lo permite
Si no tienes permisos para ejecutar Set-ExecutionPolicy (por ejemplo, en un equipo de empresa gestionado por políticas de grupo) o simplemente prefieres no cambiar la configuración del sistema, puedes saltarte la restricción únicamente para esta ejecución, sin necesidad de permisos de administrador:
powershell
powershell -ExecutionPolicy Bypass -File "C:\ruta\a\Renombrar-Espacios.ps1" -Ruta "C:\ruta\a\tu\carpeta"Y en modo prueba:
powershell
powershell -ExecutionPolicy Bypass -File "C:\ruta\a\Renombrar-Espacios.ps1" -Ruta "C:\ruta\a\tu\carpeta" -DryRunEsta opción aplica el "bypass" solo a ese proceso de PowerShell concreto: no modifica ninguna configuración persistente del sistema ni afecta a otros scripts.
Uso básico
El script acepta dos parámetros:
| Parámetro | Obligatorio | Descripción |
|---|---|---|
-Ruta | Sí | Carpeta raíz desde la que empezar a renombrar de forma recursiva. |
-DryRun | No | Si se indica, solo muestra qué cambiaría, sin renombrar nada realmente. |
Ejecutar en modo real
powershell
.\Renombrar-Espacios.ps1 -Ruta "C:\Users\Juanjo\Documentos"Ejecutar en modo prueba (recomendado antes de aplicar cambios)
powershell
.\Renombrar-Espacios.ps1 -Ruta "C:\Users\Juanjo\Documentos" -DryRunEn modo -DryRun, el script imprime en pantalla cada renombrado que haría, pero no modifica ningún archivo ni carpeta. Es la forma más segura de comprobar el resultado antes de tocar datos reales.
Ejecutar sobre una unidad de red
powershell
.\Renombrar-Espacios.ps1 -Ruta "Z:\nominas y documentacion administrativa"Cómo interpretar la salida
Durante la ejecución, el script muestra una línea por cada archivo o carpeta renombrado:
Archivo: 'E:\recycle\Informe de Vida Laboral Sepbre.2024.pdf' -> 'E:\recycle\Informe_de_Vida_Laboral_Sepbre.2024.pdf'
Carpeta: 'Z:\nominas y documentacion administrativa' -> 'Z:\nominas_y_documentacion_administrativa'Si un nombre destino ya existe, el script no sobrescribe nada; lo omite y avisa:
[AVISO] Ya existe, se omite: Z:\nominas_y_documentacion_administrativa\archivo.pdfSi ocurre un error al renombrar un elemento concreto (por ejemplo, por bloqueo del archivo o permisos), el script lo marca en rojo y continúa con el resto:
[ERROR] No se pudo renombrar: Al finalizar, se muestra un resumen:
Listo. Elementos renombrados: 42
Elementos con error (omitidos): 1Detalles técnicos de funcionamiento
- Recolección del árbol completo. El script usa
Get-ChildItem -Recurse -Forcepara obtener todos los archivos y carpetas, incluidos los ocultos, dentro de la ruta indicada. - Ordenación por profundidad. Los elementos se ordenan según el número de niveles de su ruta, de mayor a menor profundidad, para procesar siempre primero el contenido más anidado.
- Distinción entre archivos y carpetas. Las carpetas no tienen la propiedad
DirectoryName(solo los archivos la tienen); el script usaParent.FullNamecuando el elemento es una carpeta. - Compatibilidad con rutas largas. Antes de cada operación de renombrado, el script añade el prefijo
\\?\(rutas locales) o\\?\UNC\(rutas de red) a la ruta de origen, indicando a Windows que omita el límite estándar de 260 caracteres. - Tolerancia a fallos. Cada renombrado individual se ejecuta dentro de un bloque
try/catch; un fallo puntual no interrumpe el procesamiento del resto del árbol.
Recomendaciones de uso
- Ejecuta siempre primero con
-DryRunsobre carpetas con datos importantes, para revisar el resultado antes de aplicar los cambios. - Haz una copia de seguridad si vas a procesar carpetas críticas (nóminas, documentación administrativa, correos exportados, etc.), especialmente en la primera ejecución.
- Cierra los archivos que puedan estar abiertos en otros programas (Outlook, Word, Excel, PDF) antes de ejecutar el script, ya que un archivo bloqueado no podrá renombrarse.
- Revisa los avisos y errores al final de la ejecución; los elementos omitidos por "ya existe" no producen pérdida de datos, pero conviene revisarlos manualmente si es relevante.
Limitaciones conocidas
- El script solo reemplaza el carácter espacio. No normaliza otros caracteres problemáticos como tildes,
ñ, guiones, paréntesis o el carácter–(guión largo), que en algunos casos también dan problemas en rutas o URLs. - No incluye una función de deshacer. Se recomienda probar con
-DryRuny/o mantener una copia de seguridad antes de ejecutar en modo real sobre datos importantes. - En rutas de red muy largas, aunque el prefijo
\\?\UNC\soluciona la mayoría de casos, algunos servidores NAS o SMB antiguos pueden seguir teniendo limitaciones propias no relacionadas con PowerShell.
Código fuente
El script completo (Renombrar-Espacios.ps1) se entrega como archivo independiente junto a este manual.
<#
.SYNOPSIS
Renombra recursivamente archivos y carpetas reemplazando espacios por guiones bajos.
.DESCRIPTION
Recorre una ruta de forma recursiva y renombra todos los archivos y carpetas
cuyo nombre contenga espacios, sustituyendo cada espacio por "_".
Procesa primero los elementos mas profundos para no romper rutas.
.PARAMETER Ruta
Carpeta raiz desde la que empezar a renombrar.
.PARAMETER DryRun
Si se indica, solo muestra los cambios que se harian, sin aplicarlos.
.EXAMPLE
.\Renombrar-Espacios.ps1 -Ruta "C:\Users\Juanjo\Documentos"
.EXAMPLE
.\Renombrar-Espacios.ps1 -Ruta "C:\Users\Juanjo\Documentos" -DryRun
#>
param(
[Parameter(Mandatory = $true)]
[string]$Ruta,
[switch]$DryRun
)
if (-not (Test-Path -LiteralPath $Ruta -PathType Container)) {
Write-Host "Error: la ruta '$Ruta' no existe o no es una carpeta." -ForegroundColor Red
exit 1
}
Write-Host "Procesando: $Ruta"
if ($DryRun) {
Write-Host "*** MODO PRUEBA (DryRun): no se modificara nada ***`n" -ForegroundColor Yellow
}
# Prefijo que le indica a Windows que soporte rutas largas (> 260 caracteres)
function Convertir-RutaLarga {
param([string]$Path)
if ($Path -match '^\\\\') {
# Ruta de red \\servidor\recurso -> \\?\UNC\servidor\recurso
return $Path -replace '^\\\\', '\\?\UNC\'
}
else {
return "\\?\$Path"
}
}
# Obtenemos TODOS los elementos (archivos y carpetas) de forma recursiva,
# y los ordenamos por profundidad de ruta descendente (mas profundos primero)
# para que renombrar una carpeta no invalide las rutas de su contenido.
$items = Get-ChildItem -LiteralPath $Ruta -Recurse -Force |
Sort-Object { ($_.FullName -split '\\').Count } -Descending
$contador = 0
$errores = 0
foreach ($item in $items) {
if ($item.Name -match ' ') {
$nuevoNombre = $item.Name -replace ' ', '_'
# DirectoryName solo existe en archivos; en carpetas usamos Parent.FullName
if ($item.PSIsContainer) {
$carpetaPadre = $item.Parent.FullName
}
else {
$carpetaPadre = $item.DirectoryName
}
$destino = Join-Path -Path $carpetaPadre -ChildPath $nuevoNombre
if (Test-Path -LiteralPath (Convertir-RutaLarga $destino)) {
Write-Host "[AVISO] Ya existe, se omite: $destino" -ForegroundColor Yellow
continue
}
$tipo = if ($item.PSIsContainer) { "Carpeta" } else { "Archivo" }
Write-Host "$tipo`: '$($item.FullName)' -> '$destino'"
if (-not $DryRun) {
try {
$origenLargo = Convertir-RutaLarga $item.FullName
Rename-Item -LiteralPath $origenLargo -NewName $nuevoNombre -ErrorAction Stop
$contador++
}
catch {
Write-Host " [ERROR] No se pudo renombrar: $($_.Exception.Message)" -ForegroundColor Red
$errores++
}
}
else {
$contador++
}
}
}
Write-Host "`nListo. Elementos renombrados: $contador"
if ($errores -gt 0) {
Write-Host "Elementos con error (omitidos): $errores" -ForegroundColor Red
}
