#!/usr/bin/perl -w ############################################################################### # # File: disk_usage.pl # # Function: # # Author(s): Michael Jelks # # Copyright: Copyright (c) 2003 Michael Jelks # All Rights Reserved. # # Source: Started anew. # # Notes: # # Change History: # 10/15/03 Started source # # ############################################################################## #Unbuffers output- good for nph-scripts $| = 1; use strict; # the syntax is : ./disk_usage.pl [directory] -t=[threshold value] my $output; my ($list, @total_list); my $dir = $ARGV[0]; my $threshold = 0; my $subtotal = 0; my $total = 0; #clear the screen for readability system "clear"; #exit program if they don't enter a [valid] directory if (!$dir) { print "You need to supply a directory before we can process the folders\n"; exit; } if (!-d $dir) { print "\"$dir\" is not a valid directory - check to make sure it exists\n"; exit; } #if ($dir !~ /\/$/) { print "pre-dir manip: $dir\n"; $dir =~ s/(.+)/$1\//; print "post-dir manip: $dir\n"; exit; } #this adds a trailing slash - needed for du -ks later on... if ($dir !~ /\/$/) { $dir =~ s/(.+)/$1\//; } #add threshold values if -t argument exists - otherwise use initialized value up top if ($ARGV[1]) { $threshold = $ARGV[1]; $threshold =~ s/-t=(.+)/$1/; print "Checking for values >= " .$threshold."MB\n"; } #process the header $total_list[0] = $dir; &process_list(\@total_list,$total,"header"); @total_list = (); #first get a list of all files for the specified directory $output = &command_line("ls","-1F",$dir); $list = &parse_list($output); #then get the subtotal for any files that exceed the threshold value foreach (@$list) { $output = &command_line("du", "-ks" , "\"" . $dir . $_ . "\""); my $list2 = &parse_list($output); $subtotal = &process_list($list2,$subtotal,""); } #process the subtotal (only if threshold specified) $total_list[0] = $dir; &process_list(\@total_list,$subtotal,"subtotal"); @total_list = (); #then get the grand total for the entire directory $output = &command_line("du", "-ks" , "\"" . $dir . "\""); push(@total_list,$output); $total = &process_list(\@total_list,$total,"total"); print "\n\n\n"; exit; ############################################################################### # # SUBS # ############################################################################### sub command_line { my ($command, $argument, $parameter) = @_; my $system; $system = `$command $argument $parameter`; return $system; } sub parse_list { my $output = shift; my (@list,@new_list); my $listing; @list = split(/\n/,$output); foreach $listing (@list) { # if it's not a symlink - push into new array if ($listing !~ /.+\@$/) { #remove any funny stuff at the end - * / etc. $listing =~ s/(.+)\W$/$1/; push (@new_list, $listing); } } #sort file listing case-insensitve - gives human alphabetical order... @new_list = sort {lc($a) cmp lc($b)} @new_list; return \@new_list; } sub process_list { my ($list, $total, $type) = @_; my ($name, $size); ######################## FORMATS ############################################# # format HEADER = SIZE Path/Filename Size (in MB) ------------------------------------------------------------------------------- . format ITEMS = @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<@>>>>>>>>>>>>>> $name, $size . format FOOTER = ------------------------------------------------------------------------------- . # ############################################################################## foreach (@$list) { #extract the byte count and file/dir name from the list if ($_ =~ /^(\d+)\s+(.+)/) { $size = $1; $name = $2; #format the output to 2 decimals - print only if threshold exceeded $size = sprintf("%.2f", ($size/1024)); if ($type eq "total") { &setHandle("FOOTER"); write; &setHandle("ITEMS"); $name = "Total for directory -> " . $name; write; } elsif ($size >= $threshold) { &setHandle("ITEMS"); write; #print $name ." => " . $size . "MB\n"; $total += $size; } } elsif ($type eq "subtotal" && $threshold > 0) { $size = $total; $name = $_; #print "$size $name";exit; &setHandle("FOOTER"); write; &setHandle("ITEMS"); $name = "Total for search -> " . $name . " >= $threshold MB: "; write; } elsif ($type eq "header") { &setHandle("HEADER"); write; } } return $total; } sub setHandle { my $handle = shift; my $oldhandle = select STDOUT; $~ = $handle; select ($oldhandle); }