¿Cómo puedo cambiar el nombre de los archivos por lotes en bash?

5

Tengo algunos archivos como este:

database1-backup-01-01-2011.sql
database2-backup-01-01-2011.sql

... etc. Quiero cambiarles el nombre para agregar AM, así:

database1-backup-01-01-2011-AM.sql
database2-backup-01-01-2011-AM.sql

¿Cuál es la forma más concisa de hacerlo desde bash shell?

Nathan Long
fuente

Respuestas:

13

Otra opción:

for i in *.sql ; do
    mv -v $i ${i%.sql}-AM.sql
done

Esto recorre todos los archivos .sql y los renombra para terminar en -AM.sql.

PROTIP: Úselo en $(command)lugar de `command`en sus scripts (y líneas de comando), hace que las citas y el escape sean menos pesadillas.

chrish
fuente
Agradable, la forma más concisa hasta ahora.
Nathan Long
7

Prueba este pequeño script:

#!/bin/sh

FILES=`ls *.sql`
for FILE in ${FILES}
{
    BASE=`basename ${FILE} .sql`
    mv ${FILE} ${BASE}-AM.sql
}

Acabo de escribir eso desde la memoria, así que si no funciona al 100%, no me culpes (es decir, haz una copia de seguridad de tus datos primero;))

Cómo funciona:

Recopile todos los archivos en una variable (podría poner esto dentro de for en su lugar, pero me gusta mantener las cosas fáciles de leer):

FILES=`ls *.sql`

Recorre cada archivo:

for FILE in ${FILES} { ... }

Obtenga el nombre de archivo sin .sql:

BASE=`basename ${FILE} .sql`

Cambie el nombre del archivo, agregando -AM.sql al nombre base:

mv ${FILE} ${BASE}-AM.sql
Majenko
fuente
2
Se puede quitar la línea FILES=`ls *.sql`y reemplazar ${FILES}por *.sql, el desarrollo del forro se hará cargo de la búsqueda de los archivos.
Lekensteyn
Esta no es la forma más concisa, pero aprecio la legibilidad y la explicación. Si voy a hacer esto desde la línea de comandos, prefiero escribir lo que muestra chrish, pero si lo estuviera guardando como un script, definitivamente usaría tu forma de legibilidad.
Nathan Long
1
@ Matt Jenkins: la legibilidad no aumenta al agregar otro lscomando. Mantenlo simple. Por cierto, creo que {son tímidos, es mejor reemplazarlos por doy done:for ...; do ...; done
Lekensteyn
1
@ Matt Jenkins: FILES=`ls *.sql`<- ahí. La expansión de Shell está incorporada, no es necesario este extra ls.
Lekensteyn
2
Bueno, perdóname por escribir código portátil. ls..es solo una fuente de archivos que el script podría manejar; sería trivial cambiarlo para usar, por ejemplo, una lista predefinida de archivos o argumentos de línea de comando, simplemente editando esta variable. No es necesario cambiar la estructura de for si desea darle otro uso al script. ¿No es ese el punto de este sitio? ¿Dar respuestas que sean de interés para la población general? Si eso significa hacer que sus guiones sean un poco más verbales y un poco más comprensibles, entonces no veo ningún problema, ls..ya que muestra implícitamente en qué se está trabajando.
Majenko
4

Usando la versión del script Perl de rename:

rename 's/\.sql$/-AM$&/' *.sql

Usando la util-linux-ngversión de rename(pero solo si ".sql" solo aparece al final del nombre del archivo):

rename .sql -AM.sql *.sql

Utilizando mmv:

mmv '*.sql' '#1-AM.sql'
Dennis Williamson
fuente
1

Como se sugirió un script de Perl, aquí hay un script de Ruby para hacer lo mismo:

`ls *.sql`.split("\n").each do |filename|
  new_filename = filename.split('.').join('-AM.')
  `mv #{filename} #{new_filename}`
end
Nathan Long
fuente