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 $!;
}
}