1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

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:
    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,283
    Likes Received:
    364
    Trophy Points:
    83
    [comment]By the way nice bullets.[/comment]
     

Share This Page