> -----Original Message-----
> From: Westlake, Andy [mailto:[EMAIL PROTECTED]]
> Sent: Thursday, August 30, 2001 8:02 AM
> To: '[EMAIL PROTECTED]'
> Subject: Counting all the files on a system
> 
> 
> Bit of an odd one but I need to know how many regular files 
> there are on our
> system so I knocked together a little script, see below.  
> Only problem is it
> seems to run out of memory as its running.
> Any thoughts on how I could improve it would be very 
> gratefully received, or
> is there a module I don't know about that will help?
> 

I don't know why you are running out of memory, but your script is
horribly inefficient. If you simply want to count the number of regular
files in a directory tree, this is all you need:

   use File::Find;
   $n = 0;
   find(sub { $n++ if -f $_ }, '/etc');
   print "There are regular $n files in and below /etc\n";

It appears you also want to note directories that contain more than
1000 files. This can be done with File::Find's preprocess and postprocess
options much more efficiently.

See more comments below.

> 
> 
> #!/usr/bin/perl
> #
> # /usr/local/sysadm/system/filecount.pl
> #
> # Usage ./filecount.pl
> #
> # Script to count all the files on the system with the exception
> # of the /, usr and var file systems.
> #
> # Who   Date            Modifications
> # ===   ====            =============
> # AGJW  04-Jul-2001     Initial script.
> #
> # ---------------------------------------------
> # Set up variables.
> # ---------------------------------------------
> use File::Find;
> use strict;
> my @data;
> my $name;
> my $totfiles = 0;
> my $regfiles = 0;
> my $date_extn=`date +%Y-%m-%d-%R`;
> chomp ($date_extn);
> my $logfile="/usr/local/sysadm/system/filecount.$date_extn";
> #
> open (LOGFILE, ">$logfile") || die "Cannot open $logfile for 
> writing: $!";
> open (FSTAB, "cat /etc/fstab |");

Why the pipe open? You can just open the file.
Don't forget to check for open failure.

   open(FSTAB, '</etc/fstab') or die $!;

> while (<FSTAB>) {
>   @data = split;

If you just want the second element, you can avoid the array:

    my $mount = (split)[1];

>   if ( (defined($data[1])) && !($data[1] =~ 
> m#^/proc$|^/$|^/var$|^/usr$# ) )
> {
>     print "Mount point is $data[1]\n";
>     find (\&wanted1, $data[1]);
>   }
> }
> close(FSTAB);
> close(LOGFILE);
> system "sort +1nr $logfile > $logfile.sorted";
> unlink ("$logfile");
> rename ("$logfile.sorted","$logfile");
> open (LOGFILE, ">>$logfile") || die "Cannot open $logfile for 
> writing: $!";
> print (LOGFILE " \n");
> print (LOGFILE "Total number of files is $totfiles\n");
> close (LOGFILE);
> # ---------------------------------------------
> # Define sub-routines.
> # ---------------------------------------------
> sub wanted1 {
>   return if (($_ eq ".") || ($_ eq ".."));
>   return unless -d $_;
>   $regfiles=0;
>   opendir(CURDIR,$File::Find::name);
>   while ($name = readdir(CURDIR)) {
>     if ( !( -d $name ) && !( -l $name ) ) { $regfiles += 1};
>   }
>   closedir(CURDIR);
>   if ( $regfiles >= 1000 ) {print (LOGFILE "$File::Find::name \t
> $regfiles\n")};
>   $totfiles += $regfiles;
> }

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

Reply via email to