¿Cómo puede Bash cambiar el nombre de una serie de paquetes para eliminar sus números de versión? He estado jugando con ambos expr
y %%
, en vano.
Ejemplos:
Xft2-2.1.13.pkg
se convierte en Xft2.pkg
jasper-1.900.1.pkg
se convierte en jasper.pkg
xorg-libXrandr-1.2.3.pkg
se convierte en xorg-libXrandr.pkg
bash
shell
file-rename
Jeremy L
fuente
fuente
Respuestas:
Podrías usar la función de expansión de parámetros de bash
Se necesitan comillas para los nombres de archivo con espacios.
fuente
rename "s/-[0-9.]*//" *.pkg
Si todos los archivos están en el mismo directorio, la secuencia
hará su trabajo. El comando sed creará una secuencia de comandos mv , que luego puede canalizar al shell. Es mejor ejecutar primero la canalización sin el final
| sh
para verificar que el comando hace lo que desea.Para recurrir a través de varios directorios, use algo como
Tenga en cuenta que en sed, la secuencia de agrupación de expresiones regulares tiene corchetes precedidos por una barra invertida,
\(
y\)
, en lugar de corchetes simples(
y)
.fuente
ls
en scripts. La primera variedad se puede lograr conprintf '%s\n' * | sed ...
y con algo de creatividad, probablemente también pueda deshacerse de ellased
. Bash'sprintf
ofrece un'%q'
código de formato que podría ser útil si tiene nombres de archivo que contienen metacaracteres de shell literal.Haré algo como esto:
se supone que todos sus archivos están en el directorio actual. Si no es así, intente usar buscar como lo aconsejó Javier.
EDITAR : Además, esta versión no usa ninguna función específica de bash, como otras anteriores, lo que lo lleva a una mayor portabilidad.
fuente
Aquí hay un POSIX casi equivalente a la respuesta actualmente aceptada . Esto intercambia la
${variable/substring/replacement}
expansión de parámetros solo Bash por una que está disponible en cualquier shell compatible con Bourne.La expansión del parámetro
${variable%pattern}
produce el valor devariable
con cualquier sufijo que coincidapattern
eliminado. (También hay${variable#pattern}
que eliminar un prefijo).Mantuve el subpatrón
-[0-9.]*
de la respuesta aceptada aunque quizás sea engañoso. No es una expresión regular, sino un patrón global; por lo que no significa "un guión seguido de cero o más números o puntos". En cambio, significa "un guión, seguido de un número o un punto, seguido de cualquier cosa". El "cualquier cosa" será la coincidencia más corta posible, no la más larga. (Bash ofrece##
y%%
para recortar el prefijo o sufijo más largo posible, en lugar del más corto).fuente
Podemos asumir que
sed
está disponible en cualquier * nix, pero no podemos estar seguros de que sea compatiblesed -n
con la generación de comandos mv. ( NOTA: solo GNUsed
hace esto).Aun así, bash incorporado y sed, podemos rápidamente crear una función de shell para hacer esto.
Uso
Crear carpetas de destino:
Dado
mv
que no crea carpetas de destino automáticamente, no podemos usar nuestra versión inicial desedrename
.Es un cambio bastante pequeño, por lo que sería bueno incluir esa función:
Necesitaremos una función de utilidad
abspath
(o ruta absoluta) ya que bash no tiene esta compilación.Una vez que lo tengamos, podemos generar la (s) carpeta (s) de destino para un patrón sed / renombrar que incluye una nueva estructura de carpetas.
Esto asegurará que sepamos los nombres de nuestras carpetas de destino. Cuando cambiemos el nombre, tendremos que usarlo en el nombre del archivo de destino.
Aquí está el script completo con reconocimiento de carpetas ...
Por supuesto, también funciona cuando no tenemos carpetas de destino específicas.
Si quisiéramos poner todas las canciones en una carpeta,
./Beethoven/
podemos hacer esto:Uso
Ronda de bonificación ...
Usando este script para mover archivos de carpetas a una sola carpeta:
Suponiendo que quisiéramos recopilar todos los archivos coincidentes y colocarlos en la carpeta actual, podemos hacerlo:
Nota sobre los patrones de expresiones regulares sed
En este script se aplican reglas de patrones sed regulares, estos patrones no son PCRE (Expresiones regulares compatibles con Perl). Podría tener la sintaxis de expresión regular extendida sed, usando
sed -r
osed -E
dependiendo de su plataforma.Consulte la compatibilidad con POSIX
man re_format
para obtener una descripción completa de los patrones de expresiones regulares básicas y extendidas de sed.fuente
Encuentro que el cambio de nombre es una herramienta mucho más sencilla de usar para este tipo de cosas. Lo encontré en Homebrew para OSX
Por tu ejemplo yo haría:
La 's' significa sustituto. El formulario es s / searchPattern / replacement / files_to_apply. Necesita usar expresiones regulares para esto, lo que requiere un poco de estudio, pero vale la pena el esfuerzo.
fuente
for
ysed
etc. está bien, pero es mucho más simple y rápido de usarrename
si se encuentra haciendo esto con frecuencia.rename
comando; Además, algunos tendrán una diferenterename
de comandos con diferentes características, la sintaxis y / u opciones. Esto se parece al Perlrename
que es bastante popular; pero la respuesta realmente debería aclarar esto.mejor uso
sed
para esto, algo como:calcular la expresión regular se deja como ejercicio (al igual que tratar con nombres de archivo que incluyen espacios)
fuente
Esto parece funcionar asumiendo que
quita el .pkg, luego quita - ..
fuente
-e
. Ejsed -e 's/\.pkg//g' -e 's/-.*//g'
.ls
salida y cite sus variables. Consulte también shellcheck.net para diagnosticar problemas comunes y antipatrones en scripts de shell.Tenía varios
*.txt
archivos para cambiar el nombre como.sql
en la misma carpeta. a continuación funcionó para mí:fuente
Gracias por estas respuestas. También tuve algún tipo de problema. Mover archivos .nzb.queued a archivos .nzb. Tenía espacios y otros cruft en los nombres de archivo y esto resolvió mi problema:
Se basa en la respuesta de Diomidis Spinellis.
La expresión regular crea un grupo para todo el nombre de archivo y un grupo para la parte antes de .nzb.queued y luego crea un comando de movimiento de shell. Con las cuerdas citadas. Esto también evita la creación de un bucle en el script de shell porque esto ya lo hace sed.
fuente
-n
opción de la misma manera.