Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

piglist

by hsinclai (Deacon)
on Nov 16, 2007 at 18:20 UTC ( [id://651290]=sourcecode: print w/replies, xml ) Need Help??
Category: Utility Scripts
Author/Contact Info Harold Sinclair harold@hastek.net
Description: piglist makes a formatted, sorted list of subdirectory names and their sizes in K. If the path names are longer than 44 characters, piglist reformats itself to output a 132 character wide report. piglist uses File::Find and the output of 'du', on unix/linux
#!/usr/bin/perl -w
# $Id: piglist 468 2006-12-11 01:57:35Z hsinclai $
# harold@hastek.net


use strict;
use Getopt::Std;
use File::Find;
use Cwd;


getopts('h');
our($opt_h);

my $workdir;
my $wide_term  = 0;
my @dirlist;
my %sizelist;
my $marker     = '-' x 56;
my $markerlong = $marker x 2;
my $me = $0;
$me =~ s@^\.\/|\/.*\/@@g;
my $version = '0.1';

&usage if defined $opt_h;


#---Get directory for analysis
if ( $ARGV[0] ) {
   $workdir = $ARGV[0] ;
   -d $workdir || &bad_directory; 
  } else {
   $workdir = getcwd();
} 



#---Get the dirs and sizes
finddepth( { wanted => \&dirlister }, $workdir );

for my $entryin ( @dirlist ) {
   my $dusize = qx!/usr/bin/du -s "$entryin"!;
   my $realsize = (split /\t/,$dusize)[0];
   chomp $realsize;
   $sizelist{$entryin} = $realsize;

   #to see real du output
   #system("/usr/bin/du", "-s", "$entryin");
}

#---Path names longer than about 44 will need a wider display
foreach ( keys(%sizelist) ) {
   length($_) > 44 and $wide_term = 1;
}


#---Print


#------------------Header
print "\n\n Sizes in K for $workdir\n";
$wide_term == 0 ? print ' ' . $marker . $/ : print ' ' . $markerlong  
+. $/ ;


#------------------Content
my @ordered = sort { $sizelist{$b} <=> $sizelist{$a} } keys %sizelist;

if ( $wide_term == 0 ) {
   print sprintf("%15d   ",$sizelist{$_}),  sprintf("%-65s",$_) . $/ f
+or @ordered;
} elsif ( $wide_term == 1 ) {
   print sprintf("%15d   ",$sizelist{$_}),  sprintf("%-132s",$_) . $/ 
+for @ordered;
}


#------------------Footer
print $/;
$wide_term == 0 ? print ' ' . $marker . $/ : print ' ' . $markerlong .
+ $/;
print $wide_term == 0 ? sprintf("% 57s","$me v$version") :  sprintf("%
+ 113s","$me version $version") ;
print $/x2;





#---Subs
sub dirlister {
   return if -f $_;
   return if $_ =~ /^\.\.$/;
   -d $_ and push @dirlist, $File::Find::name;
   return @dirlist;
}

sub usage
{
   print "\n  Usage:  $me [PATH]  \n";
   print '  ' . $marker . $/;
   print "          List individual size in K for subdirectories of PA
+TH\n";
   print "          If no path specified, use current working director
+y \n\n";
   exit 0;
}

sub bad_directory {
  print "\n             Error:  Cannot find directory \"$workdir\" \n\
+n"; exit 1;
}

=head1 NAME

piglist - report directory sizes

=head1 SYNOPSIS

   piglist [PATH]
   piglist -h
  
   If PATH is specified, piglist reports subdirs of PATH, and
   If PATH is omitted, the current directory is listed.
   piglist -h invokes usage. 



=head1 DESCRIPTION

   piglist makes a formatted, sorted list of subdirectory names and th
+eir sizes in K.
   
   If the path names are longer than 44 characters, piglist reformats 
+itself to output
   a 132 character wide report.

   piglist uses File::Find and the output of 'du', on unix/linux



=head1 WARNINGS

  Recursive File::Find/du can be a little expensive, and might be impo
+lite to run on
  a busy or shared machine. 

  piglist does not follow symbolic links, maybe should add this abilit
+y



=head1 BUGS AND CAVEATS

  To get a proper listing in wide format, make the terminal at least 1
+50 characters wide;
  piglist uses a few more characters for margins.

  Because of line wrapping, output in an 80x24 terminal looks bad.





=cut


#eof
Replies are listed 'Best First'.
Re: piglist
by tuxz0r (Pilgrim) on Nov 17, 2007 at 02:12 UTC
    Nice little script. I can see using this on some of the Windows/NAS servers at my office; but, in *nix land I'll almost always do
    find /usr/local -type d | xargs du -s
    Which gives
    6784 /usr/local 88 /usr/local/bin 24 /usr/local/OpenSourceLicenses 8 /usr/local/OpenSourceVersions 6664 /usr/local/share 6664 /usr/local/share/man 200 /usr/local/share/man/man1 6464 /usr/local/share/man/man3

    You might want to think about giving an option to mimic this minimal, data only output so it'd be easy to pipe the output into another script or program and not have to weed out ---- and version lines. Maybe two options, one for the version of the program (instead of outputing it by default, -version) and one for pretty formatting (-pretty-print maybe?). Just a thought. Good work, though.

    ---
    echo S 1 [ Y V U | perl -ane 'print reverse map { $_ = chr(ord($_)-1) } @F;'
    Warning: Any code posted by tuxz0r is untested, unless otherwise stated, and is used at your own risk.

      ooh good suggestion for having "bare" output .. yeah

      Note though my script sorts the list in proper order (not by just the leading number), so the output is nicer than what  find /dir -type d | xargs du -s |sort gives ya.

      Thanks! Harold

        (If I guessed correctly given your reply & code then ...) Ah, but one would use the number sorting option ...

        du ... | sort -k1,1n [-k2]

        You could get the same effect by using find /dir -type d | xargs du -s | sort -n.


        We're not surrounded, we're in a target-rich environment!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://651290]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (5)
As of 2024-04-23 23:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found