in reply to Find the size of sub dirs

Take a look at direcotories and spaced used and check out File::Find.

Replies are listed 'Best First'.
Re: Find the size of sub dirs
by roXet (Initiate) on Feb 10, 2001 at 04:52 UTC
    Thanks for pointing me in the right direction guys. I just finished the script (yeah it took me awhile, doing tech support sux0rs). Here is what I came up with, it's got some PM code in it along with mine. This was a quick hack to get it to do exctaly what I wanted, maybe the infinate wisdom of the Monks can clean it up some.
    #!/usr/bin/perl use strict; use File::Find; my $dir = shift; if (!$dir) {die "perl $0 [startdir]\n";} my @subdirs = (); my $subdirsRef = \@subdirs; my %size; &get_sub_dirs($dir, $subdirsRef); for my $foo (@subdirs) { $size{$foo} = (&dir_tree_size($foo)); } print "Subdirectory size report for $dir\n\n\n"; foreach my $key (sort keys %size) { print "$key = "; printf("%.3f", $size{$key}); print " K\n"; } print "\n\n"; sub get_sub_dirs { my ($dir, $arrayRef) = @_; opendir DIR, $dir; my @files = grep !/^\.\.?$/, readdir DIR; for my $i (@files) { if (-d $i) { push @$arrayRef, $i; } } } sub dir_tree_size { my $dir = shift; my ($i,$total); $total = 0; opendir DIR, $dir; my @files = grep !/^\.\.?$/, readdir DIR; for $i (@files) { if(-d $dir . "\\" . $i) { $total += &dir_tree_size($dir . "\\$i") } else { $total += -s $dir . "\\" . $i} } $total = $total / 1024; return $total; }
      Why are you useing File::Find if you're not actually using it? Your code could be reduced a lot if you used File::Find, and your code would be able to safely handle symlinks and other operating systems.

      If your behavior was a little simpler (relying on arguments instead of finding subdirs first):

      use File::Find; use strict; foreach my $dir (@ARGV) { my $total; find(sub { $total += -s }, $dir); print "$dir: $total\n"; }
      Preserving the behavior of your script (mostly):
      use File::Find; use File::Spec; use strict; my $cur = File::Spec->curdir; my $up = File::Spec->updir; foreach my $start (@ARGV) { my @dirs = &find_subdirs($start); foreach my $dir (@dirs) { my $total = 0; find sub { $total += -s }, $dir; printf "%-20s %d\n", $dir, $total; } print STDERR "$start: No subdirectories\n" unless @dirs; } sub find_subdirs { my $start = shift; unless(opendir(D, $start)) { warn "$start: $!\n"; next; } my @dirs = map { -d "$start/$_" && !-l "$start/$_" && $_ ne $cur && $_ ne $up ? "$start/$_" : () } readdir(D); closedir(D); @dirs; }
        The reason the File::Find is in there is because I put that script together from a couple of others I was working with, and the use got left in there on accident.