¿Cómo quitar un nombre de archivo de caracteres especiales?

Tengo un archivo con un nombre como "Fecha de hoy.txt"

Lo que me interesa es eliminar todos los caracteres especiales usando la terminal, como:

" - , ' ' [ 

La razón de esto es que los conecto en un script más tarde y es demasiado dolor de cabeza tener en cuenta y cambiar los nombres individualmente.

Los espacios " " y los guiones bajos "_" y el alfabeto "AZ, az" están bien, al igual que reemplazar los caracteres en lugar de borrarlos.

Al principio pensé que el comando de terminal "iconv" podría ayudarme convirtiendo a una codificación más simple, pero probé varias de las codificaciones y parece que podría estar equivocado.

Sé que las expresiones regulares pueden ayudarme, pero lamentablemente no las conozco bien. Encontré esta pregunta que parece relacionada, pero no sé cómo implementarla o si cubre los mismos casos que el mío.

La razón por la que publiqué esto aquí es porque esta pregunta podría ser exclusiva del conjunto de caracteres que admite OSX para los nombres de archivo y la codificación que utiliza... aunque es más probable que no tenga ni idea de lo que estoy hablando.

De forma anticipada, muchas gracias por su ayuda.

Edito: el comando

sed 's/[!@#\$%^&*()]//g'

Parece funcionar muy bien, pero no puedo hacer que funcione para mi caso de uso original y otros:

' ` "

Escapar de ellos tampoco funciona. Soy muy nuevo en bash scripting, así que tengan paciencia conmigo.


Edición 2: publicar esto aquí o tendría que esperar 6 horas.

Además de la Respuesta de Alan Shutko, me gustaría agregar mi propia solución que encontré.

awk '{gsub(/[[:punct:]]/,"")}1'

Estoy un poco indeciso de publicar esto ya que no puedo explicarlo bien.

Awk, como dice su página de manual, se usa para "lenguaje de escaneo y procesamiento dirigido por patrones". La función gsub busca y reemplaza todas las apariciones de la expresión regular que ingresa. La parte gsub se vería así:

gsub("a","b")

Donde en mi ejemplo, todas las apariciones de a serían reemplazadas por b. Como en el comentario anterior, [[:punct:]] suena como si representara todos los signos de puntuación. Sin embargo, no sé qué significa el 1 en el exterior de los corchetes.

Respuestas (4)

Si tiene un conjunto específico de caracteres que desea conservar, tr funciona muy bien.

Por ejemplo

tr -cd 'A-Za-z0-9_-'

Eliminará cualquier carácter que no esté en el conjunto de caracteres enumerados. (La -d significa eliminar y la -c significa el complemento de los caracteres enumerados: en otras palabras, se elimina cualquier carácter que no esté en la lista).

Esto es exactamente lo que estaba buscando. ¡Gracias! Al leer la página de manual, el indicador [:alnum:] es igual de efectivo para mostrar caracteres alfanuméricos. Así: tr -cd [:alphanum:] Podemos conservar los espacios incluyendo [:blank:]

Esto solo reemplazaría las comillas simples con guiones bajos:

for f in *; do mv "$f" "${f//'/_}"; done

Esto solo mantendría caracteres ASCII alfanuméricos, guiones bajos y puntos:

for f in *; do mv "$f" "$(sed 's/[^0-9A-Za-z_.]/_/g' <<< "$f")"; done

Las configuraciones regionales en_US.UTF-8usan el orden de intercalación ASCII en OS X, pero [[:alnum:]]también \whacen coincidir caracteres como äen ellos. Si LC_CTYPEes C, los caracteres de varios bytes se reemplazan con varios guiones bajos.

¿Se puede hacer esto recursivamente?

Recientemente tuve el mismo problema y tuve que quitar los nombres de archivo de todos los archivos en una carpeta de caracteres especiales. Usé este comando, que es una combinación de las dos respuestas publicadas aquí, pero también mantiene puntos. Tal vez ayude a alguien.

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

quitando el echodelante de mv "$file"ejecuta el comando.

estoy usando esto

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

eliminar el eco delante de mv "$file" ejecuta el comando.