[ top-posting fixed ]

"R. Joseph Newton" wrote:
> 
> Adriano Allora wrote:
> 
> > I need to know, in the @ARGV, when a string is the name of a directory.
> > More precisely I'd like to write a script that:
> >
> > processes the files of the textes in a dir
> > extracts the list of the sub-directories in a dir
> > in each sub-dir processes the files of the textes
> >                                 extracts the list of the sub-directories
> >                                 in each sub-dir processes the files of the textes
> >                                                                 extracts the list 
>of the sub-directories
> >                                                                         and go 
>on...
> 
> Hi Adriano,
> 
> Here is a start.  You might have to adapt it somewhat for youe specific
> uses.  It originated from a proplem Paul posed concernig a search for files
> of a given name on a single level of a directory tree, and greww from there.
>  It's taken on a bit of random testion g code also.  The indent function was
> born with this program, but never used in it.  It has since been moved to a
> *.pm file.
> 
> #!/usr/bin/perl
> use warnings;
> #use strict;

Why disable strict?


> # Utility to search filenames and text in a given folder and all subdirectoies
> # Usage: DirTreeTest.pl -f|-t $baseDir $soughtFile
> # If the first parameter is -f, the utility returns all folders containg the given 
>file.
> # If the first parameter is -t, the utility returns all files containg the given 
>text.
> 
> my $option = $ARGV[0];
> my $baseDir  = $ARGV[1];
> my $soughtFile = $ARGV[2];
> my $indentSize = 2;
> if ($option eq "-f") {
>   ListDirectoriesContainingFile ($ARGV[1], $ARGV[2], 0);

Why not:

   ListDirectoriesContainingFile ($baseDir, $soughtFile, 0);

In fact, since the contents of $soughtFile don't change, why pass it to
the subroutine at all?


> } elsif ($option eq "-t") {
>   ListFilesContainingText ($ARGV[1], $ARGV[2], 0);
> } else {
>   die "You must specify either -f or -t";
> }
> 
> sub ListDirectoriesContainingFile {
>   my $currentDir  = $_[0];
>   my $targetFile = $_[1];
>   my $indentation = $_[2];
>   my $DIR;
>   opendir $DIR, $currentDir or die "Cannot opendir $currentDir: $!";
>   my $testFile = "";
>   while (my $file = readdir $DIR )  {
>     $testFile = "$currentDir\\$file";
                              ^^
The backslash will only work on some operating systems.  How can you be
sure the OP is using that particular OS?


>     if ( -d $testFile) {
>       my $go;
>       if ($go = ($file ne "." and $file ne "..")) {
            ^^^^^
What is this variable for?


>         if (-e "$testFile\\$targetFile") {
>           print "Found in:\n---=>>$testFile\n";
>         }
>         ListDirectoriesContainingFile("$testFile",
>          $targetFile, $indentation + 2);
>       }
>     }
>   }
> }
> 
> sub ListFilesContainingText {
>   my $currentDir  = $_[0];
>   my $targetText = $_[1];
>   my $indentation = $_[2];
>   chomp $targetText;
>   my $DIR;
>   print "current directory is $currentDir\n";
>   opendir $DIR, $currentDir or die "Cannot opendir $currentDir: ";
>   my $testFile = "";
>   my $file = "";
>   while (defined($file = readdir $DIR) and $file ne "") {
                                             ^^^^^^^^^^^
While I won't say that it is impossible, I would say that it is HIGHLY
improbable that a file system would store a zero length file name.


>     $testFile = "$currentDir\\$file";
>     if ( $testFile and (-d $testFile)) {
>       if ($file eq "\." || $file eq "\.\.") {;
                      ^^               ^^^^
Periods don't have to be backslashed in strings.  Better to use unless
instead of an empty if block.


>       } else {
>         ListFilesContainingText($testFile, $targetText, ($indentation + 2));
>       }
>     }
>     else {
>       #print "file $testFile checked\n";
>       if ($file =~ /\..*\./) {
>         print " ~~~> $testFile is ugly in form\n";
                                    ^^^^^^^^^^^^
Why is this "ugly"?  Why should we care?


>       }
>       open (SEEK_FILE, $testFile) or print "can not open $testFile\n";
>       my $lineNumber = 1;

Perl provides the current line number in the $. variable (if you use a
proper while loop.)

>       my $CurrentLine = <SEEK_FILE>;
>       my $IsIt;
>       while ($CurrentLine) {
>         if ($IsIt = ($CurrentLine =~ /\b$targetText\b/)) {

What happens if $targetText contains regular expression special
characters like '.', '*', '(', etc.?

>           print "--=>> $testFile: $lineNumber \n";
>           print " |$CurrentLine \n";
>           #continue;
>         }
>         $lineNumber++;
>         $CurrentLine = <SEEK_FILE>;
>       }
>       close SEEK_FILE;
>     }
>   }
> }
> 
> sub indent {
>   my ($indentation, $textString) = @_;
>   my $indent = "";
>   $oneSpace = " ";
>   for ($i = 0; $i < $indentation; $i++) {
>     $indent = $indent.$oneSpace;
>   }
>   print "$indent$textString"; print "\n";
> }

Why re-invent several wheels which are already provided with the
standard Perl distribution?

#!/usr/bin/perl
use warnings;
use strict;
use File::Find;
use Getopt::Std;

# Utility to search filenames and text in a given folder and all
subdirectoies
# Usage: DirTreeTest.pl -f|-t $baseDir $soughtFile
# If the first parameter is -f, the utility returns all folders containg
the given file.
# If the first parameter is -t, the utility returns all files containg
the given text.

sub usage {
    print STDERR <<USAGE;
Usage:  $0 -f filename directory
            return all folders containg the given file.

        $0 -t "text" directory
            return all files containg the given text.

USAGE
    exit 0;
    }

my %opts;
getopts( 'f:t:', \%opts ) or usage;
$opts{'f'} and $opts{'t'} and usage;  # one option only
my $baseDir = shift or usage;

find( sub {
    if ( $opts{'f'} and $_ eq $opts{'f'} ) {
        print "Found in:\n---=>>$File::Find::dir\n";
        }
    elsif ( $opts{'t'} ) {
        return unless -f;
        { # local scope for @ARGV and $_
            local ( @ARGV, $_ ) = $File::Find::name;
            while ( <> ) {
                if ( index( $_, $opts{'t'} ) >= 0 ) {
                    print "--=>> $ARGV: $.\n";
                    print " |$_\n";
                    }
                }
            }
        }
    }, $baseDir );

__END__



John
-- 
use Perl;
program
fulfillment

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

Reply via email to