2009-12-02 13 views
5

Tengo un montón de archivos que estoy tratando de cambiar el nombre, me trató de hacer una expresión regular para que coincida con ellos, pero ni siquiera eso me quedé atrapado en los archivos se denominan como:¿Cómo puedo cambiar el nombre de los archivos a granel fácilmente con Perl?

Nombre de archivo 01

Nombre de archivo 100

Nombre de archivo 02

Nombre de archivo 03

etc, me gustaría una dd un "0" (cero), por detrás de cualquiera de archivo que son menos de 100, así:

Nombre de archivo 001

Nombre de archivo 100

Nombre de archivo 002

Archivo Nombre 003

Lo más parecido que pude llegar a coincidir con ellos fue utilizar este find -type d | ordenar -r | grep '[1-9] [0-9] $' sin embargo no pude encontrar la manera de reemplazarlos. Gracias de antemano por cualquier ayuda que me puedan ofrecer. Estoy en CentOS si eso es de alguna ayuda, todo esto se hace a través de SSH.

+0

¿Sus nombres de archivo en realidad contienen espacios? –

+0

Sí, se ven como: "Nombre de archivo 01" "Nombre de archivo 101" –

+1

¿Puede ampliar las "herramientas" disponibles en la máquina? ¿Tiene instalado perl, python, ruby ​​o similar? –

Respuesta

12
perl -e 'foreach $f (glob("File\\ Name*")) { $nf = $f; $nf =~ s/(\d+)$/sprintf("%03d",$1)/e; print `mv \"$f\" \"$nf\"`;}' 

Tal vez un poco exagerado, pero hace lo que se le pide.

0

Creo que su amigo mmv es su amigo aquí.

9
find . -type d -print0 | xargs -0 rename 's/(\d+)/sprintf "%03d", $1/e' 

o algo por el estilo, siempre

  1. Has GNU encontrar y GNU xargs (por -print0 y -0)
  2. Has la utilidad 'renombrar' que viene con Perl
  3. Hay solo un grupo de dígitos en el nombre del archivo. Si hay más de uno, entonces debe hacer algo con la expresión regular para que solo coincida con el número que desea reformatear.
+0

Eso está cerca de algo que iba a sugerir, usando sed en lugar de xargs, entonces lo voy a +1. – shoover

+0

Sabía que xargs era el camino a seguir, simplemente no podía escribir el comando exacto. –

+0

+1 Para enumerar dependencias (posiblemente la utilidad de cambio de nombre a la que se refiere es un yum o apt-get away). – ChristopheD

2

ejecutar dos comandos, en este orden:

$ rename 's/File Name (\d)$/File Name 0$1/' * 
$ rename 's/File Name (\d\d)$/File Name 0$1/' * 

El primero cambia el nombre de todo menos de 10 y antepone un cero. El segundo cambia el nombre de todo menos de 100 y antes de cero. El resultado debe ser de tres dígitos para todos los nombres de archivo.

+0

¿En qué ambiente están esos comandos válidos? –

+0

'rename' es una utilidad que viene con la distribución de perl estándar. Ejecuté estos en Linux Bash. –

+0

[Se supone que $ representa un símbolo del sistema.] –

0

puedes hacer algo con perl o ruby.

poner todos estos archivos en el mismo directorio

dirlisting = DIR.entries('.') 

dirListing.each do |file| 
num = file.match(/\d+$/).to_i 
if num < 100 
    find the position where start the number, with index and inject the 0 there. 
end 
end 
+0

Probablemente deberías mencionar que este código es ruby ​​y no perl –

+0

si lees mi oración verás "perl O ruby" –

+0

Y es por eso que dije que deberías desambiguar el hecho de que el código es ruby. –

4

¿Es esto una cosa de una sola vez? Si es así, voy a sugerirle algo que podría parecer un error de muchos programadores aquí:

Transmita la salida de su comando (find -type d | sort -r | grep ' [1-9][0-9]$') a un archivo y use un editor junto con alguna búsqueda/reemplazo global magia para crear una secuencia de comandos que hace los cambios de nombre.

Luego tira la secuencia de comandos.

Hay poco alboroto y pocas posibilidades de que termine disparándose en el pie al intentar algún ingenioso (pero inadecuadamente depurado) delineador en las malezas de sus archivos.

+0

++! A veces es mejor usar un kludge que comprenda que aprender "magia profunda". – daotoad

+0

+1 Creo que este tipo de cosas a menudo es la solución más pragmática para uno de los requisitos –

+0

Puede ser una salida de emergencia, pero es un escape seguro ... felicitaciones. –

0
use strict; 
use File::Copy; 

my @files = glob 'File*Name*'; 

foreach my $filename (@files) { 
    if ($filename =~ m`^.*File.*Name.*?(\d+)`) { 
     my $number = $1; 
     next if ($number > 99); 
     rename $filename, sprintf("FileName%03d",$number); 
    } 
} 
+0

Eso renombra 'File Name 100' a' File Name 0100' que no es el propósito. –

+0

Sin dudas tenías razón. Se agregó un código para que no ocurra. –

1

En mi Debian funciona bien con rename, probado con 300 archivos.

perl -e 'map `touch door$_.txt`, 1..300;' 
rename 's/(\d+)\.txt/sprintf("%03d.txt", $1)/e' *.txt 
0

si el mando a distancia tiene cáscara del golpe

for i in File*; 
do 
    case "${i##* }" in [0-9][0-9]) 
     echo mv "$i" "${i% *} $(printf "%03d" ${i##* })" ;; 
    esac; 
done 

remove "eco" para hacer el cambio de nombre real

Cuestiones relacionadas