¿Cómo reemplazar un carácter con otro en todos los nombres de archivo de los directorios actuales?

41

¿Cómo cambia el nombre de todos los archivos / subdirecciones en la carpeta actual?

Digamos que tengo muchos archivos y subdirecciones que están con espacios y quiero reemplazar todos los espacios con un guión bajo.

File 1
File 2
File 3
Dir 1
Dir 3

debería cambiarse de nombre a

File_1
File_2
File_3
Dir_1
Dir_3
NobbZ
fuente

Respuestas:

36

Si necesita cambiar el nombre de los archivos en subdirectorios también, y su findadmite el -execdirpredicado, entonces puede hacerlo

find /search/path -depth -name '* *' \
    -execdir bash -c 'mv -- "$1" "${1// /_}"' bash {} \;

Gracias a @glenn jackman por sugerirme una -depthopción findy hacerme pensar.

Tenga en cuenta que en algunos sistemas (incluidos los GNU / Linux), es findposible que no pueda encontrar archivos cuyo nombre contenga espacios y también secuencias de bytes que no formen caracteres válidos (típico con archivos multimedia con nombres con caracteres no ASCII codificados en un juego de caracteres) diferente de la configuración regional). Establecer la configuración regional en C(como en LC_ALL=C find...) resolvería el problema.

enzotib
fuente
Tendría que usar find -maxdepth 1para hacer exactamente lo que el OP le pidió sobre la operación en la carpeta actual.
Caleb
1
Use la -depthopción de búsqueda , y puede deshacerse de él sort.
Glenn Jackman
@glenn jackman: gracias, ahora entiendo que mi solución estaba mal.
enzotib
2
Cambiar -name '* *'a -name '*_*'y el cambio "${1// /_}"a"${1//_/.}"
enzotib
1
@kroiz: se llama "sustitución de patrones". Puede encontrarlo en bashla página de manual de.
enzotib
34

En cualquier shell, puede recorrer los archivos cuyo nombre contiene un espacio. Reemplazar los espacios con guiones bajos es fácil en bash, ksh y zsh con la ${VARIABLE//PATTERN/REPLACEMENT}construcción.

for x in *" "*; do
  mv -- "$x" "${x// /_}"
done

En Debian, Ubuntu y derivados, puede usar Perl rename(otras distribuciones envían un programa diferente como rename, y ese programa no es útil aquí).

rename 's/ /_/g' *

Una solución zsh obligatoria:

autoload zmv
zmv '(*)' '${1// /_}'

Una solución POSIX obligatoria:

for x in *" "*; do
  y=$(printf %sa "$x" | tr " " "_")
  mv -- "$x" "${y%a}"
done
Gilles 'SO- deja de ser malvado'
fuente
¿Qué significa la 'g' al final del comando "renombrar"? No lo vi en el manual.
JulianLai
¿Cómo renombrar solo el directorio? No quiero cambiar el nombre del archivo.
JulianLai
@JulianLai s/…/…/gsignifica reemplazar todas las ocurrencias. No está muy bien explicado en el manual . Si desea cambiar el nombre de los directorios, hay formas, búsquelo (creo que lo he visto antes) y si no puede encontrarlo, haga una nueva pregunta.
Gilles 'SO- deja de ser malvado'
gran ... esto me ayudó a cambiar el nombre de todos los _MG_blah.JPGa IMG_blah.JPG.
Abinash Dash
13

Puede usar renamepara esto (aquí asumiendo el de util-linux, no el de perl):

cd /path/to/dir
rename ' ' _ *\ *

Esto encontrará todos los espacios de archivos y directorios en el nombre y reemplazará el espacio con un guión bajo. Dado que utiliza la coincidencia de archivos glob, debe estar en el directorio correcto para comenzar.

Si desea hacer coincidencias recursivas, puede hacerlo, pero es posible que tenga que ejecutarlas renameun par de veces para capturar cualquier elemento en los directorios que hayan cambiado de nombre:

cd /path/to/dir
shopt -s globstar
rename ' ' _ **/*\ *
!!; !!
Caleb
fuente
2
" renameCambiará el nombre de los archivos especificados reemplazando la primera aparición de from en su nombre por to ". Por lo tanto, esto solo funcionará para archivos con un solo espacio en su nombre. (Podría llamar renameen un bucle, pero no es realmente la herramienta correcta aquí.)
Gilles 'SO- deja de ser malvado'
2

Otra opción sería mmv, si está instalada.

mmv \*\ \* \#1_#2
glglgl
fuente
Esto solo cambia el primer espacio en a _, no funciona nombres con múltiples espacios.
Gilles 'SO- deja de ser malvado'
Oups, tienes razón. Perdón por la confusion.
glglgl
1

En Debian / Ubuntu, basándose en las respuestas de Caleb y Gilles, esto es lo que me funcionó para cambiar el nombre de los archivos de forma recursiva:

cd /path/to/dir
shopt -s globstar
rename 's/ /_/g' **

Nota: para obtener una vista previa de los archivos que se renombrarán y cómo, use el -ninterruptor con rename:

rename -n 's/ /_/g' **

Otra nota: el establecimiento de globstarmarcas **coinciden con los archivos de todos los subdirectorios, así que si sólo se desea directorio actual, no lo hacen conjunto Globstar o utilizar *en lugar de **.

Una nota más: el renamecomando debe ejecutarse más de una vez para archivos con múltiples ocurrencias del término de búsqueda.

Markus Pscheidt
fuente
Eso solo funciona si los directorios no contienen espacios. (un cambio de nombre de a b/c da a_b/c_dno funcionaría, primero deberías cambiar el nombre a b/c da a b/c_d, y luego a ba a_b).
Stéphane Chazelas
@Stephane: ¿Significa ejecutar el mismo renamecomando dos veces?
Markus Pscheidt
Bueno, más bien tantas veces como haya niveles anidados de directorios con espacios. Idealmente, primero desea recorrer la profundidad del directorio y convertir solo el nombre base del archivo como en la solución aceptada. También tenga en cuenta que bash **excluye los archivos de puntos y atraviesa los enlaces simbólicos.
Stéphane Chazelas
0

Si no eres un flash en las expresiones regulares (¡no lo soy!), Y puedes ejecutar aplicaciones diseñadas para kde (ya sea que utilices kde - k desktop o tienes sus bibliotecas instaladas), entonces krename es una gran utilidad gráfica que le permite ver el antes y el después antes de comprometerse con los cambios. Tiene una serie de transformaciones simples como opciones y también admite expresiones regulares. Incluso puede combinar varias transformaciones secuenciales en un solo cambio de nombre para que no tenga que diseñar una sola transformación compleja que lo haga todo a la vez. También tiene una opción para continuar cambiando el nombre de los mismos archivos después de aplicar un cambio de nombre.

No lo uso con tanta frecuencia, pero cuando lo hago, realmente hace el trabajo de manera rápida y fácil. Realmente es útil al cambiar el nombre de varios archivos multimedia descargados para que pueda administrarlos de manera uniforme en su sistema. Ayuda a descargar el manual de krename por separado para que pueda consultarlo mientras usa el programa.

http://www.krename.net/

Joe
fuente