fdupe 查找重复文件的Perl脚本代码

图:

代码如下:

#!/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癧\r\n]$鞍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: $fsize\n\n";
    for (@{$dupes{$i}}) {
        print $$_,"\n";
    }
  }
}

close F1;
close F2;

(0)

相关推荐

  • 使用perl清理电脑上重复文件实现代码(续)

    复制代码 代码如下: #!/usr/bin/perl use File::DirWalk; use File::Basename; use Data::Dumper; use warnings; use strict; my $dw = new File::DirWalk; my %files; fileparse_set_fstype("MSWin32"); $dw->onFile( sub { my ($file) = @_; push @{$files{basename($

  • perl去除重复内容的脚本代码(重复行+数组重复字段)

    假如有这样的一段序列:1 2  1 2  2 1  1 3  1 4  1 5  4 1 我们需要得到如下的结果:1 3  1 5  2 1  4 1 那么,请借助以下的perl脚本来实现. 代码一: 复制代码 代码如下: #!/bin/perluse strict;  use warnings;  my $filename;  my %hash;  my @information;  my $key1;  my $key2;  print "please put in the file lik

  • fdupe 查找重复文件的Perl脚本代码

    图: 复制代码 代码如下: #!/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 ackn

  • 用Python自动清理电脑内重复文件,只要10行代码(自动脚本)

    给定一个文件夹,使用Python检查给定文件夹下有无文件重复,若存在重复则删除 主要涉及的知识点有: os模块综合应用 glob模块综合应用 利用filecmp模块比较两个文件 步骤分析 该程序实现的逻辑可以具化为: 遍历获取给定文件夹下的所有文件,然后通过嵌套循环两两比较文件是否相同,如果相同则删除后者. 实现问题的关键就变成了 如何判断两个文件是否相同? 在这里我们可以使用filecmp模块,来看看官方的介绍文档: filecmp.cmp(f1, f2, shallow=True) 比较名为

  • Python实现清理重复文件功能的示例代码

    目录 前置 查找.删除重复文件 GUI制作 GUI界面设计 逻辑设计 效果展示 在电脑上或多或少的存在一些重复文件,体积小的倒没什么,如果体积大的就很占内存了,而如果自己一个一个查看文件是否重复,然后再删除,还是很要命的. 为此,我用python制作了一个删除重复文件的小工具,核心代码很简单,就十行代码,不管什么类型的文件都可以一键删除! 前置 PySimpleGUI库用来创建可视化界面,os操作文件,只需要这两个库: import os import PySimpleGUI as sg os为

  • Python实现检测文件的MD5值来查找重复文件案例

    平时学生交上机作业的时候经常有人相互复制,直接改文件名了事,为了能够简单的检测这种作弊行为,想到了检测文件的MD5值,虽然对于抄袭来说作用不大,但是聊胜于无,以后可以做一个复杂点的. # coding: utf8 import hashlib import os from collections import Counter import sys reload(sys) sys.setdefaultencoding('utf-8') def get_md5_01(file_path): md5

  • FTP自动上传文件的perl脚本以及配置文件

    本应用程序设计的几个基本理念是:工具箱再利用:尽可能利用已有的工具:简化运行步骤:不引入过多的业务逻辑,满足的需求越简单越好. 所以,我们定义了本应用程序依赖于以下几个工具的运行:ActivePerl-5.8.4.810-MSWin32-x86Upload.plUpload.config 我们将主要的执行逻辑都放在Perl源文件Upload.pl中了,配置文件为Upload.config. 这个perl文件将执行的任务是, 按照指定的文件夹目录,自动将该文件夹下的所有文件上传到指定ftp站点的指

  • 查找目录下同名但不同后缀名文件的shell脚本代码

    因为后台录入的同事,上传文件的时候,给文件取了相同的名字,但不同的后缀名,由于文件路径非常深,大概十层左右,每一层又有几十个文件,所以人工找起来非常麻烦,所以写了个脚本,帮他们实现查找指定目录下所有子目录及文件,找出相同文件名,不同后缀的文件,然后,手动保留其中一个. 复制代码 代码如下: #!/bin/bash  #判断一下脚本参数的问题  if [ $# -ne 1 ];then     echo "Usage find_same.sh direcroty"     exit  f

  • 在指定目录查找指定后缀文件的shell脚本代码

    复制代码 代码如下: #!bin/sh  # 在指定位置查找指定后缀的文件,包括子目录  # 用法:  # findf $1 $2  # 第一个参数为后缀  # 查找指定后缀的文件并打印出来  # link:www.jb51.net# date:2013/2/26 f()  {    list=`find $2|grep "/.$1/>"`    for i in $list      do      echo $i    done  } # 打印用法  print()  { 

  • 两段Perl脚本代码(数组应用与say用法)

    一.数组应用 复制代码 代码如下: #!/usr/bin env perl@zeng = `top -b -n 1`;foreach (@zeng) {print "$_\n";} 二.say的用法:自动换行 复制代码 代码如下: #!/user/bin env perluse 5.010; #表示使用perl 5.10的版本.say "Hello World!";my @fred = above_average(1..10);print "\@fred

  • perl ping检测功能脚本代码

    我的第一个用于生产环境的perl脚本,虽然不是很优秀,但也迈出了扎实的一步 :)领导有任务,给一批IP列表,ping每一台机器,如果没有响应就发邮件通知,通知的邮件需要分开,不能通知一个列表,得一封一封的通知.用到email::send模块,因为需要用到Gmail 复制代码 代码如下: #!/usr/bin/perl use warnings; use strict; use Email::Send; use Email::Send::Gmail; use Email::Simple::Crea

随机推荐