Elimine los espacios en blanco iniciales de archivos, carpetas y sus subcarpetas

Elimine los espacios en blanco iniciales de archivos, carpetas y sus subcarpetas

Se me ocurrió esto, pero desafortunadamente no afecta ningún archivo/carpeta en subcarpetas.

find . -exec rename "s/^\s+//" {} \;

Estructura de carpetas:

foo
|-- \ bar
`-- \ foo1
    |-- \ bar1
    `-- \ foo2
        `-- \ bar2

Respuesta1

El cambio de nombre debe realizarse de abajo hacia arriba

El problema es que necesitas cambiar el nombre de los directorios.de abajo a arriba. De lo contrario, el comando intentará cambiar el nombre de los archivos y directorios que se encuentran dentro de carpetas ya movidas (renombradas) y, por lo tanto, ya no podrá encontrarlos.

Aquí es donde se puede utilizar python's , en combinación conos.walk()topdown=False

En un pequeño guión:

#!/usr/bin/env python3
import os
import shutil
import sys

for root, dirs, files in os.walk(sys.argv[1], topdown=False):
    for f in files:
        if f.startswith(" "):
            shutil.move(root+"/"+f, root+"/"+f.strip())
    for dr in dirs:
        if dr.startswith(" "):
            shutil.move(root+"/"+dr, root+"/"+dr.strip())

Usar

  • Copie el script en un archivo vacío, guárdelo comono_space.py
  • Ejecútelo con el comando:

    python3 /path/to/no_space.py /path/to/directory/to/rename
    

Respuesta2

Como se señaló en otras respuestas, el problema principal es que ^ancla el inicio delcamino, en lugar del inicio del nombre del archivo. Hay varias formas de solucionar esto con findy rename: probablemente la más segura sería usar -execdiren lugar de -execpara que todos los componentes de la ruta se reduzcan a ./y luego reemplacen el patrón.\./\s+

Además, si está cambiando el nombre de los directoriosposiblemente incluyendo antepasados ​​de otros archivos/directorios a los que se les cambiará el nombre, entonces deberías hacer un recorrido en profundidad primero.

Poniendo todo junto,

find . -depth -name ' *' -execdir rename -vn -- 's#\./\s+##' {} +

o (funcionalmente equivalente, pero es un poco más fácil de ver lo que está sucediendo) usando una "mirada hacia atrás" de longitud cero para el separador de ruta

$ find . -depth -name ' *' -execdir rename -vn -- 's#(?<=\./)\s+##' {} +
./ bar2 renamed as ./bar2
./ foo2 renamed as ./foo2
./ bar1 renamed as ./bar1
./ foo1 renamed as ./foo1
./ bar renamed as ./bar

[NOTA: elimine el -nuna vez que esté seguro de que hace lo que desea]

Respuesta3

Creo que el problema está en el formato de salida de buscar, que incluye la ruta completa. Entonces para bar2 tendrás

./ foo1/ foo2 /bar2

ese cambio de nombre no se entenderá correctamente.

Una solución es utilizar un script para hacer cada carpeta de forma recursiva así:

#!/bin/bash
# if argument given consider it is the directory to parse
if [ -n "$1" ]; then
    cd "$1"
fi
# rename all files in current folder
find . -maxdepth 1 -printf '%f\0'  | xargs -0r -n 1 rename -nono 's/^\s+//'
# No, repeat for all subfolders with current script (we are in the subfolder)
find . -maxdepth 1 -type d -not -name '.' -print0 | xargs -0r -n 1 "$(readlink -f $0)"

información relacionada