【问题标题】:How to compare the content of multiple txt file in bash shell and delete the one (file) which is duplicate如何比较bash shell中多个txt文件的内容并删除重复的一个(文件)
【发布时间】:2014-08-26 21:42:52
【问题描述】:

我正在尝试使用 Mac OS 来实现这一点,尝试通过使用 fdupes 来实现类似但没有奏效。这是我想要实现的目标:

  • “alpha”目录中有 100 个文件
  • 选择一个文件 A 并将其与目录 'alpha' 中剩余的每个文件进行比较
  • 如果文件 A 的内容与任何文件匹配(重复),则删除重复文件
  • 移至文件 B,并与剩余文件进行比较,然后执行相同操作(检查是否重复)
  • 重复相同的操作,直到检查所有文件的重复项。其余文件应该是唯一的

更新

我修改了一些类似于我在这里找到的东西,但我必须多次运行它才能取出重复项。它不会在一次运行中检测到重复项(必须多次运行才能检测到重复项)。不确定它是否正常工作

use Digest::MD5;
%check = ();
while (<*>) {
    -d and next;
    $fname = "$_";
    print "checking .. $fname\n";
    $md5 = getmd5($fname) . "\n";
    if ( !defined( $check{$md5} ) ) {
        $check{$md5} = "$fname";
    }
    else {
        print "Found duplicate files: $fname and $check{$md5}\n";
        print "Deleting duplicate $check{$md5}\n";
        unlink $check{$md5};
    }
}

sub getmd5 {
    my $file = "$_";
    open( FH, "<", $file ) or die "Cannot open file: $!\n";
    binmode(FH);
    my $md5 = Digest::MD5->new;
    $md5->addfile(FH);
    close(FH);
    return $md5->hexdigest;
}

【问题讨论】:

    标签: bash perl shell


    【解决方案1】:

    您应该限制读取每个文件内容的次数:

    1. 使用Path::Class 或其他类似方法清点文件。

      一个。构建与文件大小和MD5::Digest 相关的哈希到文件名列表。

    2. 仅比较可能的重复项。匹配文件大小和摘要。

    以下内容未经测试:

    use strict;
    use warnings;
    
    use Path::Class;
    use Digest::MD5;
    
    my $dir = dir('.');
    
    my %files_per_digest;
    
    # Inventory Directory
    while ( my $file = $dir->next ) {
        my $size   = $file->stat->size;
        my $digest = do {
            my $md5 = Digest::MD5->new;
            $md5->addfile( $file->openr );
            $md5->hexdigest;
        };
        push @{ $files_per_digest{"$size - $digest"} }, $file;
    }
    
    # Compare likely duplicates only
    for my $files ( grep { @$_ > 1 } values %files_per_digest ) {
        # Sort by alpha
        @$files = sort @$files;
        print "Comparing: @files\n";
    
        for my $i ( reverse 0 .. $#files ) {
            for my $j ( 0 .. $i - 1 ) {
                my $fh1 = $files->[$i]->openr;
                my $fh2 = $files->[$j]->openr;
    
                my $diff = 0;
                while ( !eof($fh1) && !eof($fh2) ) {
                    $diff = 1, last if scalar(<$fh1>) ne scalar(<$fh2>);
                }
    
                if ( $diff or !eof($fh1) or !eof($fh2) ) {
                    print "   $files->[$i] ($i) is duplicate of $files->[$j] ($j)\n";
                    $files->[$i]->remove();
                    splice @$files, $i, 1;
                }
            }
        }
    }
    

    【讨论】:

    • 我正在尝试关注(修改了另一个用户的脚本)。它检测到一些重复项,但是当我运行脚本时,它再次检测到一些重复项.. 依此类推,直到看不到更多重复项。刚刚修改了我原来的帖子以反映鳕鱼。
    【解决方案2】:

    我过去使用 rdfind 取得了很好的成功。它非常准确、快速,而且似乎比 fdupes 运行得更精简。根据RDFind's web site(http://rdfind.pauldreik.se/),可以使用MacPorts安装。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-24
      • 2018-03-14
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      • 2020-12-28
      相关资源
      最近更新 更多