¿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
rename
que viene con elperl
paquete admite expresiones regulares:Alternativamente,
La
-i
bandera harárename
uso 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
rename
utilidad de util-linux es la predeterminada. Esta utilidad es completamente incompatible con Perlrename
.Todos: Primero, verifique si Perl's
rename
está disponible bajo el nombreprename
.Debian: el cambio de nombre de Perl debería ser el predeterminado. También está disponible como
prename
. Sinrename
embargo, el ejecutable está bajo el control de/etc/alternatives
y, por lo tanto, podría haberse modificado a algo diferente.archlinux: Ejecutar
pacman -S perl-rename
y 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 ,
rename
se puede instalar en OSX usando homebrew a través de:Descarga directa:
rename
también está disponible en Perl Monks:fuente
rename
estés hablando. El de util-linux -2.24.2-1.fc20.x86_64 no admite expresiones regulares.rename
que estaba utilizando el OP se parece a laperl
versión y no a lautil-linux
versión.rename
pá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-rename
y supongo que puedes alias.Reemplazaría todos esos
tr
comandos, con unsed
comando 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
mv
invocación por archivo, por lo que probablementerename
sea mejor. Aunque esto debería funcionar dado solo un POSIXmv
en$PATH
y 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
$IFS
un poco de imaginación (¿enferma?) .Entonces, el primer bit es bastante sencillo:
tee
canaliza 5 copias de su entrada, el documento aquí llamadoCGEN
dd
bloquea su entrada por nuevas líneas a 90 bytes por bloque y canaliza eso a ...sed
une 2 de esos bloques en dos\n
caracteres ewline, pone'
comillas simples a los resultados y antepone la cadenatouch --
para cada ciclo de línea antes de pasar a ...sh
que luego ejecuta todas las entradas como comandos de shellEl
#CGEN
poco aunque ... Bueno, en pocas palabras ...la parte inferior
printf
imprime 252 0sel siguiente del último recibe 252
''
argumentos de cadena nula y para cada uno imprime el contenido de$n
seguido por la cadena" $i "
eval
interpreta los argumentos del siguienteprintf
antes de imprimir los resultados de esa interpretación como números octales precedidos por 2 barras diagonales inversas por piezael último
printf
imprime los valores de byte para esos octales 2 a la vez seguido de la cadena-_ ---___
para cada par$n
se inicializa en una ecuación que se incrementará$i
en uno para cada evaluación, excepto que omite los valores 10, 39 o 47 - (que son\n
ewline, 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
+printf
set -- '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 six
es 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
sh
ciclo 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
bash
yksh
, y siendo un poco más detallado con la lógica:Elimina
echo
cuando estés seguro de que hace lo que quieres que haga.El
tr
comando 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