I'm using Perl 5.6.0 on Linux.

I've written a program to take a given directory passed in via command
line,
traverse the directory, and for each user who owns a file in that
directory,
print out their total usage.

My first attempt captured the directory using `ls -alR` and storing the
results in
an array. It worked, but I figured I might get more speed by using
File::Find and
File::stat. Now I have that program written, but there are some parts of
it that  I'm
hoping to improve, and some parts I took from my O'Reilly Perl book, so
I don't
quite understand. I'm hoping you can help.

####################

In the following chunk of code, why is it necessary to put the \ before
the &Match ?
It's a reference, I guess, but I haven't wrapped my brain around it.
Is there a better way to pull out the uid and size of the file?
What about my if then else statement that checks to see if
$report{$owner} is defined?
Back months ago when I didn't use -w and strict, I used to be able to
say $report{$owner}+=$size,
but now I get complaints. Is there a better way to do this?

find (\&Match, "$ARGV[0]");
sub Match {
  my $file=$File::Find::name;
  if (-f $file) {
    my $stats=stat($file);
    my $owner=$stats->uid;
    my $size=$stats->size;
    (defined $report{$owner}) ? ($report{$owner}+=$size) :
($report{$owner}=$size);
  }
}

#################

In the following chunk of code, $_ is a valid uid.
Is there a shorter, better way to get the username into the $name
variable?

my @info=getpwuid($_);
my $name;
(defined $info[0]) ? ($name=$info[0]) : ($name='unknown');

#################

My program follows (70 lines including lots of blank spaces), in case
someone wants to use it themselves or
even if some generous person has more comments to make. I understand
that this might not be the right place for a big "RFC on my program", so
feel
free to stop reading at this point .Thanks very much in advance.

            Pete

#!/usr/bin/perl -w

use strict;
use File::Find;
use File::stat;

my %report;
my $threshhold=750*1024*1024 # Default is 750 MB

Args();                      # Print help message and quit, change
threshhold

find (\&Match, "$ARGV[0]");  # Uses File::Find, matches using sub Match
Report();

#### SUBROUTINES ####

sub Args {
   # Quit the program if no directory specified or threshhold is not an
integer.
  if ((!defined $ARGV[0]) or (!-d $ARGV[0]) or ((defined $ARGV[1]) and
($ARGV[1]!~/^\d+$/))) {
    print <<HELP;
Usage:
  gethogs directory [threshhold in MB]

Default threshhold is $threshhold.

HELP
    exit;
  } else {
    $threshhold=$ARGV[1] if (defined $ARGV[1]);
  }
}

 sub Match {
  my $file=$File::Find::name;
  if (-f $file) {
    my $stats=stat($file);
    my $owner=$stats->uid;
    my $size=$stats->size;
    (defined $report{$owner}) ? ($report{$owner}+=$size) :
($report{$owner}=$size);
  }
}

sub Report {                                 # Sort on values of hash,
not on keys.
  foreach (sort { $report{$b} <=> $report{$a} } keys %report) {
    if ($report{$_} >= $threshhold) {
      my @info=getpwuid($_);
      my $name;
      (defined $info[0]) ? ($name=$info[0]) : ($name='unknown');
      printf("%12s %12s\n",$name,Format($report{$_}));
    }
  }
}

sub Format {      # Must be a better way, I think
  my ($x)=@_;
  if ($x<1024) {
    return (sprintf("%6.2f  B", $x));
  }
  $x=$x/1024;
  if ($x<1024) {
    return (sprintf("%6.2f kB", $x));
    return "$x kB";
  }
  $x=$x/1024;
  if ($x<1024) {
    return (sprintf("%6.2f MB", $x));
    return "$x MB";
  }
  $x=$x/1024;
    return (sprintf("%6.2f GB", $x));
}



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to