Cambiar el nombre a granel, cambiar el prefijo

53

¿Cómo puedo reemplazar masivamente el prefijo para muchos archivos?

Tengo muchos archivos como

  • TestSRConnectionContext.h
  • TestSRConnectionContext.m

Me gustaría cambiarlos a

  • CLConnectionContext.h
  • CLConnectionContext.m

¿Cómo haría esto?

ErikTJ
fuente

Respuestas:

38
for name in TestSR*
do
    newname=CL"$(echo "$name" | cut -c7-)"
    mv "$name" "$newname"
done

Utiliza la sustitución del comando bash para eliminar los primeros 6 caracteres del nombre de archivo de entrada a través de cut, antecede CLal resultado y lo almacena $newname. Luego cambia el nombre antiguo al nuevo nombre. Esto se realiza en cada archivo.

cut -c7-especifica que solo los caracteres después del índice 7 deben ser devueltos desde la entrada. 7-es un rango que comienza en el índice 7 sin fin; es decir, hasta el final de la línea.

Anteriormente, lo había usado cut -b7-, pero -cdebería usarse en su lugar para manejar codificaciones de caracteres que podrían tener múltiples bytes por carácter, como UTF-8.

mrb
fuente
Gracias, yo también tengo esto ahora mismo. Marcado como respuesta. Thx
ErikTJ
Esto funciona bien, gracias. ¿Puedes explicar qué hace -b7-? ¿Es esta referencia a la lista de bytes? ss64.com/bash/cut.html
publicado el
@imjared Actualizó la respuesta con más detalles.
mrb
56

Yo diría que lo más simple es usar el renamecomando que es común en muchas distribuciones de Linux. Hay dos versiones comunes de este comando, así que revise su página de manual para encontrar cuál tiene:

## rename from Perl (common in Debian systems -- Ubuntu, Mint, ...)
rename 's/^TestSR/CL/' *

## rename from util-linux-ng (common in Fedora systems, Red Hat, CentOS, ...)
rename TestSR CL *

Si desea utilizar la versión de util-linux-ng en un sistema Debian, está disponible con el nombre rename.ul

carandraug
fuente
77
Una advertencia: renameexisten múltiples versiones de en la naturaleza. Consulte su renamedocumentación local para descubrir cómo usar la suya.
jw013
Para eliminar el alias dorename TestSR '' *
Bsienn
hmm ... rename "\<pre\>" "" *->Unterminated <> operator at (user-supplied code).
Flash Thunder
33

La expansión de parámetros de Shell es suficiente para transformaciones simples como esta. La sustitución de comandos es menos eficiente debido a la necesidad de generar procesos adicionales (para la sustitución de comandos en sí y el cut/ sed).

for f in TestSR*; do mv "$f" "CL${f#TestSR}"; done
jw013
fuente
Explicación: TestSR*encuentra los archivos, CL${f#TestSR}será el nuevo nombre. Las cosas después de la #serán sustituidas por el nombre del archivo ( f).
Joe Eifert
4

Aquí hay una manera:

ls *.{h,m} | while read a; do n=CL$(echo $a | sed -e 's/^Test//'); mv $a $n; done
  • ls *.{h,m} -> Buscar todos los archivos con extensión .h o .m
  • n=CL -> Agregar un prefijo CL al nombre del archivo
  • sed -e 's/^Test//' -> Elimina el prefijo de prueba del nombre del archivo
  • mv $a $n -> Realiza el cambio de nombre
Eric
fuente
3

Puedes probar con:

for i in TestSR*; do mv ${i} ${i/#TestSR/CL}; done

Consulte man bash(sección "Expansión de parámetros") para más detalles.

Francesco Turco
fuente
1

Bueno, no fue tan difícil como yo.

$ for f in TestSR*.m; do mv $f CL$(echo $f | cut -c7-); done;
$ for f in TestSR*.h; do mv $f CL$(echo $f | cut -c7-); done;
ErikTJ
fuente
1
En caso de que sirva para el futuro, no tiene que repetir los comandos para sus dos patrones; se puede utilizar (por ejemplo): for f in TestSR*.[mh], for f in TestSR*.{m,h}, for f in TestSR*.m TestSR*.h.
mrb
1

Si necesitas algo más placentero puedes hacerlo

perl -e 'for(@ARGV) { rename($_, $n) if( ($n = $_ ) =~ s/^TestSR/CL/) }' *
usuario1146332
fuente