Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Re^2: file comparison

by graff (Chancellor)
on Jun 27, 2009 at 00:46 UTC ( [id://775206]=note: print w/replies, xml ) Need Help??


in reply to Re: file comparison
in thread file comparison

You have a ways to go yet. Your foreach loops won't do what you want, for a few different reasons:
  • The parameter you pass to md5_base64 needs to be the data in the file, not the name of the file.
  • When you read a file to get its md5, you need to include the path name with the file name (because readdir only returns the file name, not the path).
  • Rather than just printing the md5s, you should store them, compare them, and print (and/or act on) the results of the comparisons.

Apart from that, your loop usage could be a little better. Also, I think it ends up being easier to use the "object" style interface to Digest::MD5. You still have to open each file, but then you can just pass the file handle to the module.

Here's an approach that includes checking file size in combination with the md5 checksum, and reports 3 different problem cases that might come up:

#!/usr/bin/perl use strict; use warnings; use Digest::MD5; die "Usage: $0 remoteDir localDir\n" unless ( @ARGV == 2 and -d $ARGV[0] and -d $ARGV[1] ); my ( $remote, $local ) = @ARGV; my %md5; my $digest = Digest::MD5->new(); for my $dir ( $local, $remote ) { opendir DIR, $dir or die "$dir: $!\n"; while ( my $f = readdir( DIR )) { next unless -f "$dir/$f"; if ( open( my $fh, "<", "$dir/$f" )) { $digest->new; $digest->addfile( $fh ); $md5{$f}{$dir} = join( " ", -s _, $digest->b64digest ); } else { warn "Open failed for $dir/$f: $!\n"; } } } for my $file ( sort keys %md5 ) { if ( $md5{$file}{$remote} and ! $md5{$file}{$local} ) { warn sprintf( "%s: found on remote, not found in local path\n" +, $file ); } elsif ( $md5{$file}{$remote} ne $md5{$file}{$local} ) { warn sprintf( "%s: remote/local difference: %s vs. %s\n", $fil +e, $md5{$file}{$remote}, $md5{$file}{$local} ); } else { unlink "$remote/$file" or warn sprintf( "%s: unable to delete remote copy: %s\n", $f +ile, $! ); } }
(updated to remove an unnecessary "next" from the latter for loop. Also added error checking when reading the files for their md5s.)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://775206]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (7)
As of 2024-04-24 09:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found