#!/usr/bin/perl use warnings; use strict; use File::Find; use Digest::MD5; use File::stat; my %iseen; my %file; my $dev; my $debug = 1; sub hash { my $filename = shift; open my $f, "<", $filename or die "$filename: $!"; my $md5 = Digest::MD5->new; $md5->addfile($f); my $digest = $md5->digest; return $digest; } sub action { my $filename = $File::Find::name; my $st = lstat($filename) or die "$filename: $!"; return unless -f _; return if $iseen{$st->ino}++; die "changé de périf: $dev != $st->dev" if $dev != $st->dev; my $hash = hash $filename; if ($file{$hash}) { if ($debug) { print "lien de $file{$hash} vers $filename\n" } unlink $filename or do { warn "$filename: $!"; return }; link $file{$hash}, $filename or die "$filename: $!"; # if the second file we saw has several links, we'll want to # check also those links now we deleted the first one $iseen{$st->ino} = 0; } else { $file{$hash} = $filename; } } foreach (@ARGV) { if (! $dev) { $dev = stat($_)->dev; } find({wanted => \&action, no_chdir => 1}, $_); }