Atajo de shell / bash para cambiar el nombre de los archivos en una carpeta

¿Hay un atajo en Shell / Bash que puede cambiar el nombre de todos los archivos en una carpeta basada en una expresión regular u otros criterios? Lo que estoy buscando aquí está en mis documentos de carpeta, que digamos unos 100 archivos de texto con la siguiente convención de nomenclatura:

-doc-.txt. 

Necesito cambiar el nombre de todos los archivos con la convención dada anteriormente a solo:

 doc-.txt 

¿Hay un trazador de líneas que me puede ayudar con lo anterior?

Sugeriría algo como esto:

 for i in *-doc-*.txt; do mv $i ${i/*-doc-/doc-}; done 

${i/*-doc-/doc-} reemplaza la primera ocurrencia de *-doc- con *-doc- .

Si necesita hacer más de un reemplazo (vea el comentario número 1), necesita usar la variante ${var//Pattern/Replacement} . Si necesita reemplazar el comienzo del nombre, necesita usar ${var/#Pattern/Replacement} ; si necesita reemplazar el extremo (es decir, la extensión), necesita usar ${var/%Pattern/Replacement} forma.

Ver http://tldp.org/LDP/abs/html/parameter-substitution.html#EXPREPL1 para más detalles

Si ha rename 's/^.*-doc-/doc-/' *.txt rename entonces, rename 's/^.*-doc-/doc-/' *.txt debería hacer el truco.

Hay prename , que le permite usar REGEX:

 prename 's/^.*-doc-(.*\.txt)$/doc-$1/' *.txt 

Use la opción -n para simular:

 prename -n 's/^.*-doc-(.*\.txt)$/doc-$1/' *.txt 

Nota: Esto se envía como rename de rename en muchas distribuciones de Linux, pero no en todas, así que estoy usando el nombre canónico para la utilidad que viene con Perl.

El comando de cambio de nombre integrado en la mayoría de Linux, por ejemplo, lo hará fácilmente.

Personalmente, prefiero las expresiones regulares también, razón por la cual he llevado este guión durante mucho tiempo (léase: desde finales de los 80 o principios de los 90):

 #!/usr/bin/perl ($op = shift) || die "Usage: $0 expr [files]]\n"; if(!@ARGV) { @ARGV = ; chop(@ARGV); } for (@ARGV) { $was = $_; eval $op; die $@ if $@; if ($was ne $_) { print "rename($was,$_)\n"; rename($was,$_); } } 

Que, cuando está instalado le permite hacer cosas como esta:

 script-name 's/.*-doc(.*).txt/doc$1.txt/' *.txt 

Si desea recurse en subdirectorios, también hay:

 find . -maxdepth N -type f -name "$pattern" | sed -e 'p' -E -e "s/$str1/$str2/g" | xargs -n2 mv 

En el sistema que admite automáticamente Regexps extendido, puede dejar el -E

Ventajas:

  • recurrencias en subdirectorios
  • puedes controlar el máximo de la recursión
  • puede cambiar el nombre de los archivos y / o directorios (-type f | d)

Desventajas:

  • expresiones regulares un poco más complicadas, porque tiene que quitar la ruta para obtener el nombre del archivo

(respuesta modificada desde aquí )

 mmv "*-doc-*" "doc-#2" 

El comando mmv significa “movimiento masivo”

Si no te importa la herramienta externa, aquí hay una: rnm ( página web )

Para su problema particular, el comando sería:

 rnm -rs '/.*-doc-/doc-/' *.txt 

O

 rnm -rs '/.*-(doc-.*\.txt)/\1/' *.txt 

Puede encontrar más ejemplos / documentos aquí .

encontrar . -name ‘* scss’ | xargs -L1 -I {} echo {} {} | sed ‘s / css.scss $ / scss /’ | xargs -L1 mv

por ejemplo, si tiene un grupo de archivos que terminan en “.css.scss” y desea cambiarles el nombre para que terminen simplemente con “.scss” (es decir, eliminar la parte .css)

ajustar la expresión regular y encontrar argumentos a sus necesidades