A diferent find . -type f -exec grep main {} -H \;

Discussion in 'Perl' started by oleber, May 4, 2007.

  1. oleber

    oleber New Member

    Joined:
    Apr 23, 2007
    Messages:
    37
    Likes Received:
    2
    Trophy Points:
    0
    Occupation:
    Software Developer (Perl, C/C++ and Java)
    Location:
    Hamburg, Germany
    Home Page:
    http://oleber.freehostia.com/
    After allot of searches like 'find . -type f -exec grep main {} -H \;' I implemented a small program :eek:.

    ;) This program uses the normal 'file' shell command to check if a file is a text file.

    ;) Ignores files inside /CVS/. They are there, but who cares?

    ;) Clearly separates the results from different files

    and can show how to use:
    :cool: the module File::Find
    :cool: creating subroutine locally
    :cool: the grep, the last, the -f, ...
    :cool: get the output from shell commands
    ...

    Code:
    #!/usr/bin/perl
      use strict;
      use warnings;
      use File::Find;
      
      if (grep {/^-help$/} @ARGV) {
          print "$0 [-all|-file|-help] matchRegExp [path]";
          exit;
      }
      
      my $all = grep {/^-all$/} @ARGV;
      my $justFile = grep {/^-file$/} @ARGV;
      my ($match, $initPath) = @ARGV = grep {not /^-(all|file|help)$/} @ARGV;
      
      die "just one file accepted" if scalar(@ARGV) > 2;
      die "no match" if scalar(@ARGV) == 0;
      
      $initPath = (".") if not defined $initPath;
      
      die("unrecognizable path: $initPath") if not -e $initPath;
      
      my $lastPrinted;
      
      find( sub {
          my $fileName = $_;
          my $filePath = $File::Find::name;
          
          return if $filePath =~ m|/CVS/|; # not inside CVS directory
          return if not -f $fileName; # just check files
          return if not $all and `file -b $fileName` !~ /text/i; # just text files
              
          open(my $FILE, $fileName) or die "canot open file '$fileName': $!";
      
          while (my $line = <$FILE>) {
              if ($line =~ /$match/) {
                  if ($justFile) {
                      print("$filePath\n");
                      last;
                  } else {
                      print("\n", "*"x80, "\n\n") 
                          if $lastPrinted and $lastPrinted ne $filePath;
                      $lastPrinted = $filePath;
                              
                      printf("%-50s %s", "$filePath $.:", $line);
                  }
              }            
          }
          close($FILE);
      }, $initPath);
    A 50 lines program.
     
    Last edited: May 6, 2007
  2. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    [comment]By the way nice bullets.[/comment]
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice