in reply to Re: file comparison
in thread file comparison
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:
(updated to remove an unnecessary "next" from the latter for loop. Also added error checking when reading the files for their md5s.)#!/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, $! ); } }
|
|---|