使用Perl取得两个目录下相同的文件
2013-05-31 16:04:26 阿炯

本站赞助商链接,请多关照。 得一需求,找到两个目录下内容相同的文件(文件名不一定相同),主要原理如下:
取得两个目录所有的文件大小,并以其大小的key,文件名(多个)为value的哈希数组(%file)里。后将%file里的含有两个文件以上的文件取mdsum校验和,存入以mdsum值为key,文件名为value的哈希数组(%mdsum)里。然后将%mdsum中的文件数量为两个及以上的文件信息(名称、大小、mdsum校验和)存入数组'@dupes'中。

代码开始
-----------------------------
use Data::Dumper;
use File::Find;
use Digest::md5;

my ($pdir,$sdir)=@ARGV;
die 'Please input two dir name,space separated' unless($pdir and $sdir);

sub get_duplicate_files {
#define duplicate array and files hash
my (@dupes, %files);
#create file size as key,the same size files(two dirs) as array value,such hash file var
find sub {-f && push @{ $files{ (stat($_))[7] } }, $File::Find::name;}, @_;

foreach my $size (sort {$b<=>$a} keys %files){
#skip the only one file
 next unless @{$files{$size}}>1;
 my %mdsum;
 #handle two more files,calculate the same size file's mdsumsum
 foreach my $file (@{$files{$size}}){
  open(my $fh,$file) or next;
  binmode($fh);
  push @{$mdsum{Digest::mdsum->new->addfile($fh)->hexdigest}},$file;
 }
#print Dumper(\%mdsum);
#create array dupes of same size file info:name,size,mdsumsum
foreach (keys %mdsum){
 next unless @{$mdsum{$_}}>1;
 push @dupes,{files=>$mdsum{$_},size=>$size,mdsum=>$_};
}

}
#print Dumper(\%files,\@dupes);
return @dupes;
}#func end

my @dupes=get_duplicate_files($pdir, $sdir);

#print Dumper(\@dupes);

foreach my $dupeset (@dupes) {
 printf "Files %s (of size: %d) hash: %s\n",join(",",@{$dupeset->{files}}), $dupeset->{size}, $dupeset->{mdsum};
}

-----------------------------
代码结束

使用方法:
$ getdupfiles.pl /path/dir1 /path/dir2