2012-08-04 25 views
21

Tengo un conjunto de archivos denominados como:Renombrar archivos usando expresiones regulares en Linux

Friends - 6x03 - Tow Ross' Denial.srt 
Friends - 6x20 - Tow Mac and C.H.E.E.S.E..srt 
Friends - 6x05 - Tow Joey's Porshe.srt 

y quiero cambiar su nombre como el siguiente

S06E03.srt 
S06E20.srt 
S06E05.srt 

lo que hay que hacer para hacer el trabajo hecho en la terminal de Linux? He instalado de cambio de nombre, sino T obtener errores utilizando la siguiente:

rename -n 's/(\w+) - (\d{1})x(\d{2})*$/S0$2E$3\.srt/' *.srt 

Respuesta

35

Se le olvidó un punto delante del asterisco:

rename -n 's/(\w+) - (\d{1})x(\d{2}).*$/S0$2E$3\.srt/' *.srt 

en openSUSE, RedHat, Gentoo se tienen que utilizar la versión de Perl, rename. This answer muestra cómo obtenerlo. En Arch, el paquete se llama perl-rename.

+2

OpenSUSE, RedHat, Gentoo no admite expresiones regulares en 'rename' – mmrmartin

+0

@mmrmartin: El script de cambio de nombre utilizado aquí es el escrito por Larry Wall. Se utilizó en el archivo '/ usr/bin/rename', pero tal vez se ha cambiado el nombre (sin juego de palabras)? En Debian, el nombre del script ahora es '/ usr/bin/file-rename'. – Thor

+1

openSUSE utiliza el cambio de nombre del paquete 'util-linux', no encontré ningún paquete que proporcione' file-rename', 'prename' o' perl-rename' - solo la solución de trabajo era [install using cpan] (http: // stackoverflow.com/a/32862278/1392034) para mí. – mmrmartin

7

No todas las distribuciones incluyen una utilidad rename que admite expresiones regulares como se usa en los ejemplos anteriores: RedHat, Gentoo y sus derivados, entre otros.

Las alternativas para intentar utilizar son perl-rename y mmv.

0

Puede utilizar rnm:

rnm -rs '/\w+\s*-\s*(\d)x(\d+).*$/S0\1E\2.srt/' *.srt 

Explicación:

  1. -rs: sustituir cadena de la forma /search_regex/replace_part/modifier
  2. (\d) y (\d+) en (\d)x(\d+) son dos groupes capturados (\1 y \2 respectivamente) .

Más ejemplos here.

4

Editar: encontrado una mejor manera para listar los archivos sin necesidad de utilizar IFS y ls sin dejar de ser compatible sh.

lo haría un script de shell para que:

#!/bin/sh 
for file in *.srt; do 
    if [ -e "$file" ]; then 
    newname=`echo "$file" | sed 's/^.*\([0-9]\+\)x\([0-9]\+\).*$/S0\1E\2.srt/'` 
    mv "$file" "$newname" 
    fi 
done 

guión anterior:

#!/bin/sh 
IFS=' 
' 
for file in `ls -1 *.srt`; do 
    newname=`echo "$file" | sed 's/^.*\([0-9]\+\)x\([0-9]\+\).*$/S0\1E\2.srt/'` 
    mv "$file" "$newname" 
done 
+0

¿Qué significa 'IFS = '\ n'' en este ejemplo? Me gusta porque no usa nada especial. – Szobi

+0

IFS: el separador de campo interno que se utiliza para dividir palabras después de la expansión y para dividir las líneas en palabras con el comando leído incorporado. El valor predeterminado es "" - (de man bash). Cambiarlo a '\ n' permite obtener un archivo por línea. – Creak

0

si su Linux no ofrece cambiar el nombre, se podría también utilizar el siguiente:

find . -type f -name "Friends*" -execdir bash -c 'mv "$1" "${1/\w+\s*-\s*(\d)x(\d+).*$/S0\1E\2.srt}"' _ {} \; 

uso este fragmento bastante a menudo para realizar sustituciones con expresiones regulares en mi consola.

no soy muy bueno en la concha cosas, pero por lo que yo entiendo este código, su explicación sería como: los resultados de búsqueda de su encuentran será pasado a una fiesta de mando (fiesta - c) donde su resultado de búsqueda estará dentro de $ 1 como archivo de origen. el objetivo que sigue es el resultado de una sustitución dentro de un subnivel, donde el contenido de $ 1 (en este caso solo dentro de su parámetro-substituion { // buscar/reemplazar}) también será su resultado de búsqueda. la {} se lo pasa al contenido de -execdir

mejor explicación sería apreciado mucho :)

tenga en cuenta: i única copia-pegar su expresión regular; por favor, pruébelo primero con archivos de ejemplo. dependiendo de su sistema, es posible que deba cambiar \ d y \ w por clases de caracteres como [[: digit:]] o [[: alpha:]]. sin embargo, \ 1 debería funcionar para los grupos.

1

mmv es simple pero útil. Utiliza * para cualquier cadena y ? para cualquier carácter en la secuencia de coincidencia y #X en la cadena de reemplazo para hacer referencia a la X-ésima coincidencia.

En su caso:

mmv 'Friends - 6x?? - Tow *.srt' 'S06E#1#2.srt' 

Aquí #1#2 representan los dos dígitos que son capturados por ?? (partido # 1 y # 2).

mmv también ofrece la coincidencia por [ y ] y ;, lea la página del hombre para obtener más información!

1

Realmente genial lil diddy.

xargs -n2 hace posible imprimir dos argumentos por línea. Cuando se combina con Perl's print $_ (para imprimir $ STDIN primero), se convierte en una poderosa herramienta de cambio de nombre.

find . -type f | perl -pe 'print $_; s/DVDCover/DVDCoverLabel/' | xargs -n2 mv 

Resultados de perl -pe 'print $_; s/OldName/NewName/' | xargs -n2 llegar a ser:

OldName.ext NewName.ext 
OldName.ext NewName.ext 
OldName.ext NewName.ext 
OldName.ext NewName.ext 

que no tenían rename de Perl fácilmente disponible en mi sistema.

Cuestiones relacionadas