Aprendiendo Perl, el reto: Encontrar duplicados
Dmitriy Ryajov
dryajov en gmail.com
Jue Abr 5 01:30:39 PDT 2012
Aquí esta mi versión. No hago uso de File::Find si no, utilizo opendir y
readdir directamente, esto para propósitos ilustrativos.
Esta versión, recorre (recursivamente) una lista de directorios que se
pasa como argumento o utiliza el directorio actual, desde donde se
ejecuto el script.
<==============================================================>
#!/usr/bin/env perl
use strict;
use warnings;
use Digest::MD5;
use Cwd;
my @directories = (); # list of scanned directories
my @dirs = @ARGV;
@dirs = ( getcwd ) unless scalar @dirs;
for my $dir ( @dirs ) {
scan_dir( $dir );
}
for my $dir_struct ( @directories ) {
print "Found duplicates in directory $dir_struct->{name}\n";
print "File: $_\n" for @{$dir_struct->{files}};
}
sub scan_dir {
my $directory = shift;
$directory =~ s|/?$||g; # remove trailing /
# open dir for scanning
opendir my $dh, $directory or
print "Error opening dir: $directory\n$!" &&
return; # don't die, we just want to skip this dir
my $dir_struct = {
name => $directory, # name of the scanned dir
files => [], # list of scanned files
};
my %dup_files = ();
for my $file ( readdir( $dh ) ) {
next if $file =~ /^\.{1,2}$/; # skip current and parrent dir
$file = "$directory/$file"; # fix up file name to full path
if( -d $file ) { # recurse if it's a directory
scan_dir($file);
next;
}
next if !-r $file; # skip non readble files
my $checksum = chekcsum( $file );
if ( !$dup_files{$checksum} ) {
$dup_files{$checksum} = $file;
next;
}
push @{$dir_struct->{files}}, $file;
}
# store it for later use
push @directories, $dir_struct if scalar @{$dir_struct->{files}};
}
sub chekcsum {
open( my $fh, '<', shift ) or die $!;
binmode($fh);
return Digest::MD5->new->addfile($fh)->hexdigest;
}
<==============================================================>
Saludos,
Dmitriy Ryajov.
On 03/27/2012 09:15 AM, Marcelo wrote:
> Hola,
>
> brian d foy[0] comenzó a publicar en http://www.learning-perl.com/ una
> serie de retos para la gente aprendiendo Perl. Pensé que para alguna
> gente podría ser útil tener el reto disponible en Español y no en
> Inglés, además de poder conversar sobre las soluciones también en
> Español. Hasta que no monte otra cosa, les propongo hacerlo mediante
> esta lista, si alguno tiene interés.
>
> A continuación la traducción del post que brian publicó en
> http://www.learning-perl.com/?p=286
>
> ------------------------------ 8< ------------------------------
>
> Este es el segundo reto para novatos. Voy a darles un problema que
> deberían poder resolver solo con las cosas presentes en "Learning
> Perl" (incluyendo el uso de módulos, es decir, la mayoría de Perl).
> Más o menos una semana después publicaré una solución (NdT: me
> comprometo a traducir las soluciones también).
>
> Para este reto, dado un único directorio conteniendo archivos
> posiblemente duplicados, encuentre los archivos que pueden ser
> duplicados. Solo debe imprimir los archivos duplicados e imprimir sus
> nombres. Si desea remover los duplicados, ¡asegúrese de tener un
> backup!
>
> Existen algunos módulos que pueden resultar útiles:
>
> Digest::MD5
> Digest::SHA1
>
> Si se encuentra especialmente motivado, busque también en los
> subdirectorios que encuentre.
>
> ------------------------------>8 ------------------------------
>
> Saludos y que se diviertan,
>
> Marcelo
>
> PS: Como pueden ver en el blog de Learning Perl, la gente que quiere
> recibir retroalimentación publica sus soluciones allí. Sería
> buenísimo si la gente por acá hiciese lo mismo y los demás les den
> opiniones.
>
> [0] brian es coautor de "Learning Perl" en su última edición. Él
> prefiere escribir su nombre así como aparece acá, no estoy siendo
> perezoso con las mayúsculas :-)
> __
> Costarica-pm at pm.org
> http://mail.pm.org/mailman/listinfo/costarica-pm
Más información sobre la lista de distribución Costarica-pm