Пример программы поиска одинаковых файлов

code: #perl
  1. #!/usr/bin/perl
  2.  
  3. use warnings;
  4.  
  5. my %collectedFiles;
  6.  
  7. sub compareFiles($$;$)
  8. {
  9.     my $name1=shift;
  10.     my $name2=shift;
  11.     my $bufferSize=shift // 512;
  12.     unless(open $file1, '<', $name1)
  13.     {
  14.         warn "$0: Невозможно открыть «$name1»: $!\n";
  15.         return;
  16.     }
  17.     unless(open $file2, '<', $name2)
  18.     {
  19.         warn "$0: Невозможно открыть «$name2»: $!\n";
  20.         close $file1 or warn "$0: Невозможно закрыть «$name1»: $!";
  21.         return;
  22.     }
  23.     my($buffer1, $buffer2);
  24.     my $result=0;
  25.     while()
  26.     {
  27.         my $n1=read $file1, $buffer1, $bufferSize;
  28.         unless(defined $n1)
  29.         {
  30.             warn "$0: Невозможно прочитать «$name1»: $!\n";
  31.             undef $result;
  32.             last;
  33.         }
  34.         my $n2=read $file2, $buffer2, $bufferSize;
  35.         unless(defined $n2)
  36.         {
  37.             warn "$0: Невозможно прочитать «$name2»: $!\n";
  38.             undef $result;
  39.             last;
  40.         }
  41.         last unless $n1 or $n2;
  42.         if($buffer1 ne $buffer2)
  43.         {
  44.             $result=1;
  45.             last;
  46.         }
  47.     }
  48.     close $file2 or warn "$0: Невозможно закрыть «$name2»: $!";
  49.     close $file1 or warn "$0: Невозможно закрыть «$name1»: $!";
  50.     return $result;
  51. }
  52.  
  53. sub find($);
  54. sub find($)
  55. {
  56.     my $name=shift;
  57.     if(-d $name)
  58.     {
  59.         my $dir;
  60.         unless(opendir $dir, $name)
  61.         {
  62.             warn "$0: Невозможно открыть «$name»: $!\n";
  63.             return;
  64.         }
  65.         $name='' if $name eq '/';
  66.         for(readdir $dir)
  67.         {
  68.             next if $_ eq '.' or $_ eq '..';
  69.             find("$name/$_");
  70.         }
  71.         closedir $dir;
  72.     }
  73.     elsif(-f $name)
  74.     {
  75.         push @{$collectedFiles{-s $name}->[0]}, $name;
  76.     }
  77.     else
  78.     {
  79.         warn "$0: «$name»: $!\n";
  80.     }
  81. }
  82.  
  83. sub findDups(@)
  84. {
  85.     push @_, '.' unless @_;
  86.     find($_) for @_;
  87.     for my $size(sort { $a<=>$b } keys %collectedFiles)
  88.     {
  89.         my $groups=$collectedFiles{$size};
  90.         for(my $g=0; $g<@$groups; $g++)
  91.         {
  92.             my $group=$groups->[$g];
  93.             for(my $i=1; $i<@$group; $i++)
  94.             {
  95.                 push @{$groups->[$g+1]}, splice @$group, $i--, 1
  96.                     if compareFiles($group->[0], $group->[$i]);
  97.             }
  98.             if(@$group>1)
  99.             {
  100.                 print "* Размер: $size\n";
  101.                 print "$_\n" for sort @$group;
  102.                 print "\n";
  103.             }
  104.         }
  105.     }
  106. }
  107.  
  108. findDups(@ARGV);
Поделиться:

Похожие статьи: