D&C GLug - Home Page

[ Date Index ] [ Thread Index ] [ <= Previous by date / thread ] [ Next by date / thread => ]

Re: [LUG] Find hard links

 

Jamie Andrews wrote:
> Simon's solution is pretty good. 

How about Steve's? :)

Here, however is a version that does files too

First argument is dir, second is optional file.

No args is "from here".

I appologise for line 28 (with the comment), it's a terrible bit of
code. But there is no way of stopping the Find that I can see without
calling an exit or an eval with an exit which is awful.

#! /usr/bin/perl 

use File::Find;

my ($dir,$file) = @ARGV;

$dir ||= '.';

if ($file) {
  my @files = findlinkstofile($dir,$file);
  print map { "$_\n" } @files;
} else {
  my %groups = findlinksindir($dir);
  print map { "@$_\n" } values %groups;
}

sub findlinkstofile {
  
  my ($dir,$file) = @_;

  my ($finode,$fnlinks) = (lstat($file))[1,3];
  
  return $file if $fnlinks == 1;
  
  my @files;

  File::Find::find(sub {
                     return if $fnlinks == 0; # this is rubbish
                     my ($inode,$nlink) = (lstat($_))[1,3];
                     return unless $inode == $finode;
                     push(@files, $File::Find::name); 
                     $fnlinks--;
           }, $dir);

  return @files; # though this would be odd
}

sub findlinksindir {

  my ($dir) = @_;
  my %groups;

  File::Find::find(sub {
                     my ($inode,$nlink) = (lstat($_))[1,3];
                     return unless -f && $nlink > 1;
                     push(@{$groups{$inode}}, $File::Find::name); 
                   }, $dir);
  return %groups;
}
  

-- 
The Mailing List for the Devon & Cornwall LUG
http://mailman.dclug.org.uk/listinfo/list
FAQ: http://www.dcglug.org.uk/linux_adm/list-faq.html