This program takes one argument which is the directory to search (like c:\Devel). It then counts and adds up all the lines in every .pm or .pl file in that directory and then recursively in every subdirectory. Simple but useful. And I was pleased with my implementation. I run this on windows but it should work fine in Linux as well.
use strict; #counter for the number of lines we'll get my $count = 0; #first call our subroutine with program argument count_dir($ARGV[0]); #our recursive subroutine that counts .pl|.pm file-lines sub count_dir($) { my ($dir) = @_; #try to open directory passed or return if fail unless (opendir(DIR, $dir)) { print "\tCouldn't open dir: $dir\n"; return; } #get all files in directory my @files = readdir(DIR); #go through each file in dir foreach my $file (@files) { #move on if this file is a symbol next if (length($file) < 3); #if file is a .pl|.pm then count it's lines if ($file =~ /\.pl|\.pm/) { open(FILE, "<", "$dir\\$file") or print "\tCouldn't open $file to analyze\n"; while (<FILE>) { $count++; } } #otherwise if we can make this a directory lets dive into it elsif (opendir(TDIR, "$dir\\$file")) { count_dir("$dir\\$file"); } } } #print out our results print "\nLines of Perl code in directory:\t$count\n";

Replies are listed 'Best First'.
•Re: Perl LineCount
by merlyn (Sage) on Jul 18, 2002 at 16:06 UTC
    It won't run on Unix because the directory delimiter is not a blackslash. This is why you should use File::Find instead of a hand-rolled directory recursion.

    Here's some similar code I just whipped up, doing roughly the same thing:

    use File::Find; my @topdirs = @ARGV; @ARGV = (); find sub { push @ARGV, $File::Find::name if /\.p[lm]\z/ and -f; }, @topdirs; my $count = 0; @ARGV or die "No files to process!\n"; $count++ while <>; print "Total $count lines\n";

    -- Randal L. Schwartz, Perl hacker

      Under Linux, it could be as short as:
        wc -l **/*.pm
      The syntax is that of zsh. It is much more tiring to type, but one can be more portable with:
      wc -l `find -name "*.pm"`
      It doesn't even need Perl.
Re: Perl LineCount
by John M. Dlugosz (Monsignor) on Jul 18, 2002 at 18:18 UTC
    It will get caught in an infinite loop with symbolic links, too.

    I don't like the assumption that any directory that is less than three letters in name must be the ".." stuff. Your logic is far too "implicit" or "cute" (or "accidental"?) on skipping the dot-dot's and trivially skipping files whose names are two short to have a 3-character extension.