fdupe 查找重复文件的Perl脚本代码_perl教程-查字典教程网
fdupe 查找重复文件的Perl脚本代码
fdupe 查找重复文件的Perl脚本代码
发布时间:2016-12-28 来源:查字典编辑
摘要:图:复制代码代码如下:#!/usr/bin/perl##fdupetool-findingduplicatefiles##$Id:fdupe...

图:

复制代码 代码如下:

#!/usr/bin/perl

#

# fdupe tool - finding duplicate files

#

# $Id: fdupe,v 1.7 2011/10/14 20:11:21 root Exp root $

#

# Source code Copyright (c) 1998,2011 Bernhard Schneider.

# May be used only for non-commercial purposes with

# appropriate acknowledgement of copyright.

#

# FILE : fdupe

# DESCRIPTION : script finds duplicate Files.

# AUTHOR: Bernhard Schneider <bernhard@neaptide.org>

# hints, crrections & ideas are welcome

#

# usage: fdupe.pl <path> <path> ...

# find / -xdev | fdupe.pl

#

# how to select and remove duplicates:

# redirect output to >file, edit the file and mark lines you

# wish to move/delete with a preceding dash (-)

# Use following script to delete marked files:

# #!/usr/bin/perl -n

# chomp; unlink if s/^-//;

#

# history:

# 12.05.99 - goto statment replaced with next

# 14.05.99 - minor changes

# 18.05.99 - removed confusing 'for $y'

# included hash-search

# 20.05.99 - minor changes

# 02.03.00 - some functions rewritten, optimized for speed

# 10.01.01 - hint-fix by Ozzie |ozric at kyuzz.org|

# 05.03.02 - fixed hangups by reading block/char-Devices

# 08.09.11 - skips checking of hard links

# 14.10.11 - accept file names from stdin

#

#use strict; # uncomment for debugging

$|=1;

local (*F1,*F2); my %farray = (); my $statF1;

# ------------------------------

# traverse directories

sub scan ($) {

my ($dir) = $_[0];

opendir (DIR, $dir) or die "($dir) $!:$@";

map {

(-d) ? scan ($_) : push @{$farray{-s $_}},$_

unless (-l or -S or -p or -c or -b);

} map "$dir/$_", grep !/^..?$/, readdir (DIR); closedir (DIR);

}

# ------------------------------

# get chunk of bytes from a file

sub getchunk ($$) {

my ($fsize,$pfname) = @_;

my $chunksize = 32;

my ($nread,$buff);

return undef unless open(F1,$$pfname);

$statF1 = [(stat F1)[3,1]];

binmode F1;

$nread = read (F1,$buff,$chunksize);

($nread == $chunksize || $nread == $fsize) ? "$buff" : undef;

}

# ------------------------------

# compare two files

sub mycmp ($) {

my ($fptr) = $_[0];

my ($buffa, $buffb);

my ($nread1,$nread2);

my $statF2;

my ($buffsize) = 16*1024;

return -1 unless (open(F2,"<$$fptr"));

$statF2 = [(stat F2)[3,1]];

return 0

if ($statF2->[0] > 1 && $statF1->[1] == $statF2->[1]);

binmode F2;

seek (F1,0,0);

do { $nread1 = read (F1,$buffa,$buffsize);

$nread2 = read (F2,$buffb,$buffsize);

if (($nread1 != $nread2) || ($buffa cmp $buffb)) {

return -1;

}

} while ($nread1);

return 0;

}

# ------------------------------

print "collecting files and sizes ...n";

if (-t STDIN) {

$ARGV[0] = '.' unless $ARGV[0]; # use wd if no arguments given

map scan $_, @ARGV;

} else {

while (<STDIN>) {

s癧rn]$鞍g;

push @{$farray{-s $_}},$_

unless (-l or -S or -p or -c or -b);

}

}

print "now comparing ...n";

for my $fsize (reverse sort {$a <=> $b} keys %farray) {

my ($i,$fptr,$fref,$pnum,%dupes,%index,$chunk);

# skip files with unique file size

next if $#{$farray{$fsize}} == 0;

$pnum = 0;

%dupes = %index = ();

nx:

for (my $nx=0;$nx<=$#{$farray{$fsize}};$nx++) # $nx now 1..count of files

{ # with the same size

$fptr = $farray{$fsize}[$nx]; # ref to the first file

$chunk = getchunk $fsize,$fptr;

if ($pnum) {

for $i (@{$index{$chunk}}) {

$fref = ${$dupes{$i}}[0];

unless (mycmp $fref) {

# found duplicate, collecting

push @{$dupes{$i}},$fptr;

next nx;

}

}

}

# nothing found, collecting

push @{$dupes{$pnum}},$fptr;

push @{$index{$chunk}}, $pnum++;

}

# show found dupes for actual size

for $i (keys %dupes) {

$#{$dupes{$i}} || next;

print "n size: $fsizenn";

for (@{$dupes{$i}}) {

print $$_,"n";

}

}

}

close F1;

close F2;

相关阅读
推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
  • 大家都在看
  • 小编推荐
  • 猜你喜欢
  • 最新perl学习
    热门perl学习
    脚本专栏子分类