¿Cuál es un buen comando para eliminar espacios, guiones y guiones bajos de todos los archivos en un directorio o archivos seleccionados?
Utilizo el siguiente comando con Thunar Custom Actions para reducir los nombres de archivo:
for file in %N; do mv "$file" "$(echo "$file" | tr -s ' ' | tr ' A-Z' '-a-z' | tr -s '-' | tr -c '[:alnum:][:cntrl:].' '-')"; done
Pero ese comando solo reemplaza espacios con guiones / guiones y caracteres con minúscula.
He usado el siguiente comando en la terminal para eliminar espacios de miles de nombres de archivo en una carpeta, y funcionó bastante rápido:
rename "s/ //g" *
Nuevamente, solo elimina espacios, y no guiones / guiones y guiones bajos también.
Idealmente, no quiero espacios, guiones / guiones y guiones bajos en mis nombres de archivo. Y sería genial si el comando se pudiera usar con Thunar Custom Actions en los archivos seleccionados.
shell-script
files
rename
usuario8547
fuente
fuente

rename -i "s/[-_ ]//g" *echo $file | sed -e 's/[ _-]//g'; hechoRespuestas:
La versión
renameque viene con elperlpaquete admite expresiones regulares:Alternativamente,
La
-ibandera harárenameuso del modo interactivo, indicando si el objetivo ya existe, en lugar de sobrescribir en silencio.El cambio de nombre de Perl a veces se llama
prename.El cambio de nombre de Perl frente al cambio de nombre de util-linux
En sistemas similares a Debian, el cambio de nombre de perl parece ser el predeterminado y los comandos anteriores deberían funcionar.
En algunas distribuciones, la
renameutilidad de util-linux es la predeterminada. Esta utilidad es completamente incompatible con Perlrename.Todos: Primero, verifique si Perl's
renameestá disponible bajo el nombreprename.Debian: el cambio de nombre de Perl debería ser el predeterminado. También está disponible como
prename. Sinrenameembargo, el ejecutable está bajo el control de/etc/alternativesy, por lo tanto, podría haberse modificado a algo diferente.archlinux: Ejecutar
pacman -S perl-renamey el comando está disponible comoperl-rename. Para un nombre más conveniente, cree un alias. (Punta de sombrero: ChiseledAbs)Mac OSX Según esta respuesta ,
renamese puede instalar en OSX usando homebrew a través de:Descarga directa:
renametambién está disponible en Perl Monks:fuente
renameestés hablando. El de util-linux -2.24.2-1.fc20.x86_64 no admite expresiones regulares.renameque estaba utilizando el OP se parece a laperlversión y no a lautil-linuxversión.renamepágina del manual para la versión util-linux . De todos modos, además de esa nota, lo importante es que el OP obtuvo su respuesta (y usted me votó a favor :-D).pacman -S perl-renamey supongo que puedes alias.Reemplazaría todos esos
trcomandos, con unsedcomando de sustitución, por ejemplo:fuente
Sin contar
mv, en realidad no necesitas un proceso externo para esto, puedes simplemente hacerlos explotar .Sin embargo, eso significa una
mvinvocación por archivo, por lo que probablementerenamesea mejor. Aunque esto debería funcionar dado solo un POSIXmven$PATHy un shell POSIX.Entonces, se me ocurrió una especie de demo loca para esto. El conjunto de prueba se genera como:
En primer lugar, seré el primero en reconocer que el comando anterior produce resultados que pueden obtenerse más fácilmente por otros medios. Pero es probable que otros medios no demuestren tan bien qué se podría hacer con
$IFSun poco de imaginación (¿enferma?) .Entonces, el primer bit es bastante sencillo:
teecanaliza 5 copias de su entrada, el documento aquí llamadoCGENddbloquea su entrada por nuevas líneas a 90 bytes por bloque y canaliza eso a ...sedune 2 de esos bloques en dos\ncaracteres ewline, pone'comillas simples a los resultados y antepone la cadenatouch --para cada ciclo de línea antes de pasar a ...shque luego ejecuta todas las entradas como comandos de shellEl
#CGENpoco aunque ... Bueno, en pocas palabras ...la parte inferior
printfimprime 252 0sel siguiente del último recibe 252
''argumentos de cadena nula y para cada uno imprime el contenido de$nseguido por la cadena" $i "evalinterpreta los argumentos del siguienteprintfantes de imprimir los resultados de esa interpretación como números octales precedidos por 2 barras diagonales inversas por piezael último
printfimprime los valores de byte para esos octales 2 a la vez seguido de la cadena-_ ---___para cada par$nse inicializa en una ecuación que se incrementará$ien uno para cada evaluación, excepto que omite los valores 10, 39 o 47 - (que son\newline, comillas'simples y barras/inclinadas en decimal ASCII respectivamente)El resultado final es un directorio que contiene muchos nombres de archivo realmente feos que contienen cada byte en mi juego de caracteres del 1 al 255, excepto la comilla simple (solo se omite para evitar una
sed s///declaración más ) y la/barra inclinada. Esos nombres de archivo se ven así:Ahora obtendré algunos datos sobre estos archivos:
SALIDA
Okay. Ahora finalmente, a la acción:
SALIDA
¡Éxito! Puedes verlo por ti mismo:
fuente
IFS+printfset -- 'some arbitrary' args; eval printf '"%s\n"' "$(IFS=0; printf ' "$@" %s' $(printf %025d))"new="$(IFS=" -_"; printf %s $1)"bifurca un subshell (excepto en ksh93) y tiene problemas con el seguimiento de nuevas líneas. Otra opción es usarIFS=' -_'; set -- $1; IFS=; new="$*"(y cambiar su ciclo while a un ciclo for)[ -e x ]devolverá falso sixes un enlace simbólico a un archivo no existente o no accesible.si tiene perl, generalmente tiene que cambiar el nombre. tu puedes hacer:
y muestra cómo se escribe este guión:
Este script no es compatible con el indicador -i (esta es la versión en mi sistema), pero tal vez el suyo sea compatible. ¿Qué hay de los argumentos? Primero están las expresiones regulares con formato PCRE, funciona como filtro, modifica el nombre de entrada al nombre de salida. Lista de nombres de entrada que da por asterisco '*'. por ejemplo, haces:
en real '*' se puede expandir a:
Cuando tienes archivos de conteo realmente grandes, estás en trampa. Shell expandirá su línea más de lo que acepta el sistema. entonces puede hacer una solución usando find o xargs. El uso de 'buscar' es un problema, ya que el cambio de nombre se llamará muchas veces igual al conteo de archivos en el directorio. mejor usar xargs con la opción -r. una llamada de cambio de nombre modifica muchos archivos. por ejemplo:
último problema, qué significa:
Esta es una expresión regular para modificar nombres. después de la primera '/' es el espacio. esto se detecta y se reemplaza por una cadena después del segundo '/'. Pero hay una cadena vacía que termina con el tercer '/', luego el espacio se reemplaza por nada. La opción 'g' hace que esta expresión sea repetitiva. la expresión caminará por todo el nombre desde el principio hasta el final y detectará todos los espacios.
Pero, ¿qué pasa si tienes un carácter de tabulación u otro personaje 'blanco'? Hay un reemplazo para este '\ s'. ¿Qué otros personajes innecesarios? simplemente agrégalo a la expresión. Todos se cierran con corchetes, por ejemplo:
esto es todo. ves similitud? Creo que deberías leer man perlrequick y man perlretut, esto te explica (espero) cómo funciona la expresión regular. puede usar el comando renombrar en su propio script si lo necesita.
fuente
El siguiente
shciclo de shell eliminará todos los espacios, guiones bajos y guiones de los nombres de los archivos en el directorio actual, teniendo cuidado de no sobrescribir ningún archivo existente:Para
bashyksh, y siendo un poco más detallado con la lógica:Elimina
echocuando estés seguro de que hace lo que quieres que haga.El
trcomando eliminará (-d) cualquier carácter en el conjunto de caracteres dado (' _-'). Es importante tener el guión al comienzo o al final del conjunto, o se interpretará como un rango de caracteres.fuente