使用Perl取得两个目录下相同的文件
得一需求,找到两个目录下内容相同的文件(文件名不一定相同),主要原理如下:取得两个目录所有的文件大小,并以其大小的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