¿Cómo cambiar el nombre de todos los archivos con caracteres y espacios especiales en un directorio?


10

¿Cómo puedo cambiar el nombre de todos los archivos en un directorio específico donde los archivos contienen espacios en blanco y caracteres especiales ($ y @) en sus nombres?

Intenté el renamecomando de la siguiente manera para reemplazar todos los espacios y caracteres especiales con un _:

$ ls -lrt
total 464
-rwxr-xr-x. 1 pmautoamtion pmautoamtion 471106 Jul 17 13:14 Bharti Blocked TRX Report Morning$AP@20150716.csv


$ rename -n 's/ |\$|@/_/g' *
$ ls -lrt
total 464
-rwxr-xr-x. 1 pmautoamtion pmautoamtion 471106 Jul 17 13:14 Bharti Blocked TRX Report Morning$AP@20150716.csv
$

El comando funciona pero no hará ningún cambio en los nombres de los archivos y tampoco devolverá ningún error. ¿Cómo puede solucionar esto y hay otras formas también?


1
Es posible que espere el script de cambio de nombre de perl (ref: manpages.ubuntu.com/manpages/dapper/man1/prename.1.html ) pero en cambio está obteniendo el cambio de nombre util-linux, que no funciona de la misma manera.
Jeff Schaller

Respuestas:


10

La -nbandera es para

--no actuar

Sin acción: muestra qué archivos habrían cambiado de nombre.

Entonces es normal si no tienes ningún cambio.

En cuanto a su comando, está funcionando para mí:

$ touch "a @ test"
$ ls
a @ test
$ rename -n 's/ |\$|@/_/g' *
a @ test renamed as a___test

Tal vez dependiendo de tu caparazón, tienes que escapar del |

$ rename -n 's/ \|\$\|@/_/g' *

O puede usar la […]notación para agrupar caracteres:

$ rename -n 's/[ @\$]/_/g' *

1
Intenté los tres sin la opción -n y aún así no cambiará el nombre del archivo. No doy ningún error para ninguno de los 3 tipos mencionados anteriormente. Tal vez el comando renombrar no funciona por alguna razón. ¿Hay alguna otra forma de cambiar todos los archivos en un directorio con espacios o $ o @ en sus nombres?
Ankit Vashistha

@AnkitVashistha hace rename -n 's/./_/g' *salidas algo?
fredtantini

No da nada, sin salida, sin error. Simplemente aterriza en la siguiente línea de comando.
Ankit Vashistha

rename tampoco funciona para mí para reemplazar (espacio) o ':' en Ubuntu 18.04, Bash 4.4.20 (1)
-release

7

Podrías intentarlo así:

for file in ./*Block*                                       
do echo mv "$file" "${file//[ ()@$]/_}"
done

Si está satisfecho con el resultado, elimine el echoantes mvpara cambiar el nombre de los archivos.


Una de las mejores soluciones por las que he pasado, estaba intentando esto por mucho tiempo
Sushin Pv

2

buscando un guión atractivo para eliminar caracteres especiales, así como caracteres especiales alemanes, reemplazándolos por caracteres universales para no eliminar información útil. He actualizado la última versión del guión que tenía algunos problemas menores que resultaban en:

#!/bin/bash

for file in ./*
do
  infile=`echo "${file:2}"|sed  \
         -e 's|"\"|"\\"|g' \
         -e 's| |\ |g' -e 's|!|\!|g' \
         -e 's|@|\@|g' -e 's|*|\*|g' \
         -e 's|&|\&|g' -e 's|]|\]|g' \
         -e 's|}|\}|g' -e 's|"|\"|g' \
         -e 's|,|\,|g' -e 's|?|\?|g' \
         -e 's|=|\=|g'  `
  outfileNOSPECIALS=`echo "${file:2}"|sed -e 's|[^A-Za-z0-9._-]|_|g'`
  outfileNOoe=`echo $outfileNOSPECIALS| sed -e 's|ö|oe|g'`
  outfileNOae=`echo $outfileNOoe| sed -e 's|ä|ae|g'`
  outfileNOue=`echo $outfileNOae| sed -e 's|ü|ue|g'`
  outfileNOOE=`echo $outfileNOue| sed -e 's|Ö|OE|g'`
  outfileNOAE=`echo $outfileNOOE| sed -e 's|Ä|AE|g'`
  outfileNOUE=`echo $outfileNOAE| sed -e 's|Ü|UE|g'`
  outfileNOss=`echo $outfileNOUE| sed -e 's|ß|ss|g'`
  outfile=${outfileNOss}
  if [ "$infile" != "${outfile}" ]
  then
        echo "filename changed for " $infile " in " $outfile
        mv "$infile" ${outfile}
  fi
done

exit

Resultando en:

ingrese la descripción de la imagen aquí

@don_crissti: Él está haciendo el hokus-pokus con el archivo ya que Linux tendría sus propios problemas con el manejo de caracteres especiales al mover el nombre de archivo.


1
caracteres especiales ? cuáles ?
don_crissti

Espacio, en símbolo, Ampersand ...
Matthias R. Wiora

No hay ningún problema para mover un archivo con un nombre que contenga caracteres especiales (incluida una nueva línea) ... Probablemente no esté familiarizado con los shells (y por cierto, esto no tiene nada que ver con Linux, es una función de shell ... )
don_crissti

mh bien, tal vez tengas razón
Matthias R. Wiora

1

Dado que el renamecomando no funcionó para mí por razones desconocidas y no obtengo ninguna otra respuesta para mi pregunta, intenté hacer un esfuerzo para hacer posible el cambio de nombre. Puede que este no sea el mejor enfoque para cambiar el nombre de los archivos, pero funcionó para mí y es por eso que me gustaría publicarlo como respuesta para que, si alguien más lo lee, pueda obtener ayuda para cambiar los nombres de los archivos de la manera que lo hice.

Ahora, para mí, sé que todos los archivos tendrán un texto específico en sus nombres, que es la palabra "Bloquear". Los siguientes son los nombres de archivo antes de que se realizara el cambio de nombre:

anks@anks:~/anks$ ls -lrt
total 4
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$AP@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$HP@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$CH@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$KK@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:48 Bharti TRX Block Report$UW@12Jul15.csv

Ahora he escrito un pequeño script de shell para hacer esto posible. El siguiente es el código:

#!/bin/bash

PATH="/home/ebfijjk/anks"

# Put the old filenames in a file.
ls $PATH | grep Block >> oldValues

# Put the new names without " " or "@" or "$" in another file
cat oldValues | sed 's/\$/_/g' | sed 's/\@/_/g' | sed 's/ /_/g' >> newValues

# Create a new file with Old names and New names seperated by a #.
paste -d'#' oldValues newValues >> oldAndNew

# Read the file with both old and new names and rename them with the new names.
while IFS='#'; read oldValue newValue
do
    mv "$oldValue" "$newValue"

done < oldAndNew

rm oldValues newValues oldandNew

Y eso es todo, cuando ejecuto el script, cambia el nombre de todos los nombres de archivos que tienen espacios en blanco ( ) $o @con o en _lugar de estos caracteres.


puede reemplazar cat foo | sed S1 | sed S2 | sed S3 >> barporsed -e S1 -e S2 -e S3 foo >> bar
Archemar

2
@Archemar - o simplemente sed 's/[ ()@$]/_/g'osed 'y/ ()@$/_____/'
don_crissti

Gracias don_crissti y Archemar por sus comentarios y sugerencias.
Ankit Vashistha

1

Este solo quita los caracteres especiales de los nombres de archivo

for file in *; do mv "$file" `echo $file | tr -cd '.A-Za-z0-9_-'` ; done
Námásté Egész-ség.mkv --> NmstEgsz-sg.mkv

poner echodespués ; doa prueba antes, como:

for file in *; do echo mv "$file" `echo $file | tr -cd '.A-Za-z0-9_-'` ; done

Otra solución:

rename -v 's/[^a-zA-Z0-9\.\s_-]//g' *.* && rename -v 's/[\s]/_/g' *.*
Námásté Egész-ség.mkv --> Nmst_Egsz-sg.mkv

-n opción de probar antes.


0

He estado buscando una solución a este problema por un tiempo. Trabajo en viejos sistemas cerrados que no pueden tener nuevos paquetes instalados. No tengo el renamecomando Finalmente escribí un script que parece funcionar con todos los caracteres especiales ingresados ​​por el teclado. ~@#$%^&*()-_=+[]{}\|;:",<.>?' El script cambiará el nombre de cada archivo y directorio en el directorio actual. Reemplazará todos los caracteres especiales, excepto -_.con el _carácter. La outfile=línea se puede modificar para usar un carácter diferente para el reemplazo si se desea. Reemplace |_|con |.|para usar el .personaje, por ejemplo.

#!/bin/bash

for file in ./*
do
  infile=`echo "${file:2}"|sed  \
         -e 's|"\"|"\\"|g' \
         -e 's| |\ |g' -e 's|!|\!|g' \
         -e 's|@|\@|g' -e 's|*|\*|g' \
         -e 's|&|\&|g' -e 's|]|\]|g' \
         -e 's|}|\}|g' -e 's|"|\"|g' \
         -e 's|,|\,|g' -e 's|?|\?|g' \
         -e 's|=|\=|g'  `
  outfile=`echo "${file:2}"|sed -e 's|[^A-Za-z0-9._-]|_|g'`
  mv "$infile" ${outfile} &
done

exit

0

Para mí, en Ubuntu 18.04 LTS con bash 4.4.20 (1), la versión de esta línea funcionó bien para eliminar espacios, @,: # ...

Para probar (tenga en cuenta el echocomando:

for file in ./* ; do if [[ $file == *['!'\ :@#]* ]]; then echo mv "$file" "${file//[ #()@$:]/_}"; fi; done

Ejecutar:

for file in ./* ; do if [[ $file == *['!'\ :@#]* ]]; then echo mv "$file" "${file//[ #()@$:]/_}"; fi; done
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.