Saltar al contenido

Usando Perl para cambiar el nombre de los archivos en un directorio

Solución:

Si tu ./emails directorio contiene estos archivos:

1.msg
2.msg
3.msg

entonces tu @files se verá algo así como ('.', '..', '1.msg', '2.msg', '3.msg') Pero tu rename quiere nombres como 'emails/1.msg', 'emails/2.msg', etc. Entonces puedes chdir antes de cambiar el nombre:

chdir('emails');
for (@files) {
    #...
}

Probablemente querrá comprobar el chdir valor de retorno también.

O agregue los nombres del directorio usted mismo:

rename('emails/' . $old, 'emails/' . $_) or print "Error renaming $old: $!n";
# or rename("emails/$old", "emails/$_") if you like string interpolation
# or you could use map if you like map

Es posible que desee combinar la lectura y el filtrado de su directorio utilizando grep:

my @files = grep { /^RE .+msg$/ } readdir(DIR);

o incluso esto:

opendir(DIR, 'emails') or die "Cannot open directory";
for (grep { /^RE .+msg$/ } readdir(DIR)) {
    (my $new = $_) =~ s/^RE //;
    rename("emails/$_", "emails/$new") or print "Error renaming $_ to $new: $!n";
}
closedir(DIR);

Pareces estar asumiendo glob-comportamiento similar en lugar de readdir-comportamiento similar.

El subyacente readdir La llamada al sistema devuelve solo los nombres de archivo dentro del directorio e incluirá dos entradas . y ... Esto se traslada a la readdir función en Perl, solo para dar un poco más de detalle sobre la respuesta de mu.

Alternativamente, no tiene mucho sentido usar readdir si está recopilando todos los resultados en una matriz de todos modos.

@files = glob('emails/*');

Como ya se mencionó, su secuencia de comandos falla debido a la ruta que espera y los usos de la secuencia de comandos no son los mismos.

Sugeriría un uso más transparente. Codificar un directorio no es una buena idea, en mi opinión. Como aprendí un día cuando hice un script para alterar algunos archivos originales, con la ruta codificada, y un colega mío pensó que este sería un buen script para tomar prestado para alterar sus copias. ¡Vaya!

Uso:

perl script.pl "^RE " *.msg

es decir, regex, luego una lista global de archivos, donde la ruta se indica en relación con el script, por ejemplo *.msg, emails/*.msg o incluso /home/pat/emails/*.msg /home/foo/*.msg. (múltiples globos posibles)

El uso de las rutas absolutas no dejará al usuario ninguna duda sobre los archivos a los que afectará, y también hará que el script sea reutilizable.

Código:

use strict;
use warnings;
use v5.10;
use File::Copy qw(move);

my $rx = shift;   # e.g. "^RE "

if ($ENV{OS} =~ /^Windows/) {  # Patch for Windows' lack of shell globbing
    @ARGV = map glob, @ARGV;
}

for (@ARGV) {
    if (/$rx/) {
        my $new = s/$rx//r;  # Using non-destructive substitution
        say "Moving $_ to $new ...";
        move($_, $new) or die $!;
    }
}
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *