¿Cómo puedo cambiar el nombre de archivos fácilmente a granel con Perl?
Pregunta
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:
Nombre de archivo 01
Nombre de archivo 100
Nombre de archivo 02
Nombre de archivo 03
etc, me gustaría añadir 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
Nombre de archivo 003
Lo más cerca que llegué a tanto como emparejarlos estaba usando este hallazgo de tipo D | sort -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. Im en CentOS si eso es de ninguna ayuda, todo esto se hace a través de SSH.
Solución
perl -e 'foreach $f (glob("File\\ Name*")) { $nf = $f; $nf =~ s/(\d+)$/sprintf("%03d",$1)/e; print `mv \"$f\" \"$nf\"`;}'
Un poco exagerado tal vez, pero se hace lo que se le pide.
Otros consejos
find . -type d -print0 | xargs -0 rename 's/(\d+)/sprintf "%03d", $1/e'
o algo por el estilo, siempre
- Usted tiene GNU encontrar y xargs de GNU (por
-print0
y-0
) - Usted tiene la utilidad 'Cambiar nombre' que viene con Perl
- Sólo hay un grupo de dígitos en el nombre del archivo. Si hay más de uno, entonces usted tiene que hacer algo con la expresión regular para que sea única coincide con el número que desea volver a formatear.
¿Es esto una cosa de una sola vez? Si es así, voy a sugerir algo que podría parecer ser un policía a cabo por muchos programadores aquí:
Tubería la salida de su comando (find -type d | sort -r | grep ' [1-9][0-9]$'
) a un archivo y utilizar un editor junto con un poco de búsqueda global / reemplazar la magia para crear un script que hace los cambios de nombre.
A continuación, tirar el guión.
Hay poco ruido y pocas posibilidades de que usted va a terminar pegarse un tiro en el pie por tener algún intento de un inteligente (pero insuficientemente depuradas) de una sola línea se apaga en las malas hierbas en sus archivos.
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/' *
Primero se cambia el nombre de todo menos de 10 y antepone un cero. El segundo cambia el nombre de todo menos de 100 y antepone un cero. El resultado debe ser de tres dígitos para todos los nombres de archivo.
En mi debian funciona bien con cambio de nombre, probado con 300 archivos.
perl -e 'map `touch door$_.txt`, 1..300;'
rename 's/(\d+)\.txt/sprintf("%03d.txt", $1)/e' *.txt
MMV es su amigo.
se podría hacer algo usando 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
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);
}
}
Si el mando a distancia tiene shell bash
for i in File*;
do
case "${i##* }" in [0-9][0-9] )
echo mv "$i" "${i% *} $(printf "%03d" ${i##* })" ;;
esac;
done
eliminar "eco" para hacer real el cambio de nombre