2011-12-07 16 views
39

¿Hay un atajo en Shell/Bash que puede cambiar el nombre de todos los archivos de una carpeta en función de una expresión regular u otros criterios? Lo que busco aquí está en mis documentos de la carpeta, que ha Digamos que un 100 archivos de texto con la siguiente convención de nomenclatura:Atajo de shell/bash para cambiar el nombre de los archivos en una carpeta

<longdocumentidentifier>-doc-<counter>.txt. 

tengo que cambiar el nombre de todos los archivos con la convención dada anteriormente a poco:

doc-<counter>.txt 

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

Respuesta

76

yo sugeriría algo como esto:

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

${i/*-doc-/doc-} reemplaza la primera aparición 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 , si necesita reemplazar el extremo (es decir, la extensión), necesita usar el formulario ${var/%Pattern/Replacement}.

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

+2

Esto fue útil para un caso ligeramente diferente; donde quería reemplazar todos los espacios en algunos nombres de archivo con guiones: 'for i in *; hacer mv "$ i" $ {i // \/-}; hecho'. Tenga en cuenta que para que esto funcione, tuve que citar los nombres de los archivos originales. –

+0

Lo usé para eliminar .sh de todos los nombres de las secuencias de comandos :-) 'for i in * .sh; hacer mv $ i $ {i/.sh /}; hecho'. – erm3nda

+0

@ erm3nda tenga cuidado: '$ {i/.sh /}' borra la primera coincidencia de la cadena .sh. Para asegurarte de que eliminas la extensión (que asumo que deseas) debes usar '$ {i /%. Sh /}' – Sorin

8

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 que es por eso que he estado cargando este script para un muy muy muy largo tiempo (es decir: desde finales de los años 80 o principios de los 90):

#!/usr/bin/perl 

($op = shift) || die "Usage: $0 expr [files]]\n"; 

if([email protected]) 
    { 
    @ARGV = <STDIN>; 
    chop(@ARGV); 
    } 

for (@ARGV) 
    { 
    $was = $_; 
    eval $op; 
    die [email protected] if [email protected]; 

    if ($was ne $_) 
    { 
    print "rename($was,$_)\n"; 
    rename($was,$_); 
    } 
    } 

Lo cual, cuando instalado te permite hacer cosas como esta:

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

Hay prename, que le permite utilizar Regex:

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

Utilice la opción -n para simular:

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

Nota: Este es enviado como rename en muchas distribuciones de Linux, pero no en todos ellos, entonces estoy usando el nombre canónico para la utilidad que viene con Perl.

+4

downvoter: ¿me gustaría comentar? – elias

18

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

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

comando MMV significa "movimiento de masas"

5

Si desea recursiva en subdirectorios, también hay:

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

El sistema que automáticamente soporte extendido expresiones regulares, que pueden dejar de lado el -E.

Ventajas:

  • recursivamente en subdirectorios
  • que puede controlar el maxdepth de la recursividad
  • se puede cambiar el nombre de archivos y/o directorios (de tipo F | d)

Desventajas:

  • slightl Y más complicadas expresiones regulares, ya que hay que pelar hacia fuera el camino para llegar al nombre del archivo

(respuesta modificada a partir here)

3

Si no le importa herramienta externa, entonces aquí está uno: rnm (web page)

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 here.

0

buscar. -name '* scss' | xargs -L1 -I {} echo {} {} | sed 's/css.scss $/scss /' | xargs -L1 mv

por ejemplo, si usted tiene un montón de archivos que terminan en ".css.scss" y desea cambiar el nombre de ellos para terminar con simplemente ".scss" (es decir, eliminar la parte .css)

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

Cuestiones relacionadas