Eliminar ciertos caracteres de los nombres de archivos

Eliminar ciertos caracteres de los nombres de archivos

Entiendo sólo un poco sobre esto. El siguiente comando elimina los espacios de todos los nombres de archivos.

find . -type f -name "* *.*" -exec bash -c 'mv "$0" "${0// /}"' {} \;

Me gustaría que también eliminara comas, puntos y paréntesis (   ,,  y   ), pero no sé en qué parte del comando colocar los caracteres que quiero  eliminar  ,. .()

Respuesta1

La respuesta corta es: el comando para eliminar espacios, comas, puntos y paréntesis de un nombre de archivo (en  $0) es

mv "$0" "${0//[ ,.()]/}"

Pero no uses eso...

Respuesta más larga:

  • Tu findcomando dice -name "* *.*". Que selecciona archivos cuyos nombres incluyen al menos un espacio. seguido de al menos un período.  Tiene sentido no intentar procesar archivos cuyos nombres no contengan espacios, ya que, si no hay espacios, no hay nada que eliminar. Pero no sé por qué ese comando está probando el punto. Cambiará el nombre fat cat.txta fatcat.txt, pero lo dejará hot dogintacto frank.fur ter.

    Dado que desea cambiar el nombre de los archivos con puntos en sus nombres (para eliminar los puntos), debe cambiar su -nameprueba a  -name "*[ ,.()]*".

  • Cuando se trata de nombres de archivos que no se conocen de antemano, es mejor colocarlos  --antes del primer nombre de archivo. Se puede argumentar que esto no es estrictamente necesario cuando lo haces find . … -exec …, pero es un buen hábito que debes adquirir.

  • Si tiene archivos llamados fat cat.txty f a t c a t.txt, se cambiará el nombre de ambos a fatcat.txt, y el segundo superará al primero. Pasar la -nopción (sin clobber) mv evitará que esto suceda. Pero cuidado: dejará archivos con espacios (etc.) en sus nombres, ¡y puede que ni siquiera te diga que hubo un problema!

  • Su comando actual invoca un nuevo bashproceso para cada archivo. Esto puede hacer que tarde más de lo necesario. Es preferible invocar bashuna vez y luego mvvarias veces. Entonces, incorporando todo lo anterior, tenemos

    find . -type f -name "*[ ,.()]*" -exec bash -c 'mv -n -- "$1" "${1//[ ,.()/}"' sh {} +
    

    ¡Pero espera! ¡Aún no hemos terminado! No uses lo anterior.

  • Cuando findejecuta un comando (con  -exec), pasa una ruta de acceso al archivo del comando. Si tiene un archivo llamado fat cat.txten su directorio actual, findpasará ./fat cat.txtal comando bash. El comando anterior intentará cambiar el nombre fat cat.txtde ( ./fat cat.txt) a  /fatcattxt. Si está ejecutando como root (es decir,  sudo), esto moverá sus archivos al directorio raíz, causando un gran desorden. (Lección: no ejecute comandos sudoa menos que esté seguro de que los necesita). Si no está ejecutando como root, la "buena noticia" es que el comando no hará nada.

    Entonces, ahora, sumando todo esto, obtenemos

    find . -type f -name "*[ ,.()]*" -exec bash -c 'for f do dir="$(dirname "$f")"; base="$(basename "$f")"; echo mv -n -- "$f" "$dir/${base//[ ,.()]}"; done' sh {} +
    

    Tenga en cuenta que incluí un echocomando en lo anterior, como medida de "mirar antes de saltar". Si ejecuta el comando anterior, le mostrará todos los mvcomandos necesarios. Si le parece bien, ejecute el comando nuevamente sin " echo" eliminado.


Por cierto, el comando que muestra en la pregunta fallará si algún archivo con un .en su nombre están en un directorio que tiene un espacio en su nombre.

información relacionada