OK, I am not having any luck figuring out the regex stuff.. Can somebody
share with me a perl version of grep that works or tell me the "Perl
Expression" for this..The reason I need something like perl is because the
2048 character limitation on grep... We have situations where the line can
be much longer than that.. Thanks. Steve.
We need to be able to use the -c (count) and -h (suppress filename) thanks,
Steve.
counting lines:
node13:/prod/app$ grep -c ".*"  ./client/tmp/BATCH/failed/in/PPR_RESP.log
1858571
node13:/prod/app$ peg -c  ".*"  ./client/tmp/BATCH/failed/in/PPR_RESP.log
peg: error in Perl expression: (.*)
syntax error at (eval 1) line 1, near "(."
node13:/prod/app$
AND
search for lines with . (period) in the search string
node13:/prod/app/data/journal$ grep "RES\.1\.25" sjl
RES.1.2504178found
RES.1.250417RES.1.250417RES.1.250417RES.1.250417
RES.1.250417RES.1.250417RES.1.250417RES.1.250417
node13:/prod/app/data/journal$ peg "RES\.1\.25" sjl
peg: error in Perl expression: (RES\.1\.25)
Backslash found where operator expected at (eval 1) line 1, near "RES\"
Backslash found where operator expected at (eval 1) line 1, near ".1\"
        (Missing operator before \?)
syntax error at (eval 1) line 1, near "RES\"
node13:/prod/app/data/journal$



#!/usr/local/bin/perl -w

my $VERSION = '1.00';
my $Usage = "Usage: peg [<options>|-help] <perlexpr> [<files>]\n";
my ($Dirs_specified, $Eval, $Implicit_C, $No_slurp);
my (@Files, %Options, @Perlexpr, @Warnings) = ();
my ($After, $Before) = (2, 2);
my $Perlexpr = '';

$SIG{'__WARN__'} = sub { push @Warnings, @_; };

process_ARGV();

check_Perlexpr();

$g ||= $s;

find_files() if ($d || $r);

build_Eval();

show_debug() if $D;

reset 'a-z';

eval $Eval;

die "\npeg: run time eval error:\n", @Warnings, $@,
    "\n...when eval'ing:\n$Eval\n...with input:\n$_\n";


sub process_ARGV
{
  my $options = 1;
  my $context = 'C';

  if ($_ = $ENV{'PEG_OPTIONS'}) {
    unshift @ARGV, (/^-/ ? $_ : "-$_");
  }

  while (defined ($_ = shift @ARGV)) {
    if ($f) {
      open(F, "<$_") || die "peg: can't open $_: $!\n";
      while (<F>) {
        chomp;
        push @Perlexpr, $_ unless /^$/;
      }
      close F;
      $f = 0;
    }
    elsif ($options && s/^-(?=.)//) {
      /^help$/ && help();
      while (s/^(.)//) {
        my $opt = $1;
        if ($opt =~ /^[abcdfghilnoqrstvwxyABCDEFGHLNOPQSTXYZ]$/) {
          ${$opt} = $Options{$opt} = 1;
          $context = $opt if ($opt =~ /^[ABC]$/);
        }
        elsif ($opt =~ /^\d$/) {
          while (s/^(\d)//) { $opt = (10 * $opt) + $1; }
          $After  = $opt if ($context ne 'B');
          $Before = $opt if ($context ne 'A');
          $Implicit_C = 1;
        }
        elsif ($opt eq '-') { $options = 0; }
        elsif ($opt eq 'V') { die "peg v$VERSION (Dec 1999)\n"; }
        else { die "peg: illegal option -- $opt\n$Usage"; }
      }
    }
    elsif ([EMAIL PROTECTED] || (($o || $O) && $options)) {
      push @Perlexpr, $_;
    }
    else {
      push @Files, $_;
    }
  }

  die $Usage unless @Perlexpr;

} # process_ARGV


sub check_Perlexpr
{
  my $regexp = $G || $Q || $i || $w || $x;

  foreach (@Perlexpr) {
    ($Q && !$E) || ($No_slurp ||= /[\^\$]/);
    next if ($E || !($regexp || /^\w+$/));
    $Q ? ($_ = quotemeta($_)) : (s/\//\\\//g);
    $_ = '\b' . $_ . '\b' if ($w && !$x);
    $_ = '^' . $_ . '$' if $x;
    $_ = '/' . $_ . '/';
    $_ .= 'i' if $i;
  }
  if ($O) {
    $Perlexpr .= join(",\n\t", map({"(\$Match$_ ||= (" . $Perlexpr[$_] .
"))"} (0..$#Perlexpr)),
      ('(' . join(' && ', map {"\$Match$_"} (0 .. $#Perlexpr)) . ')'));
  }
  else {
    $Perlexpr = join("\n\t|| ", map {"($_)"} @Perlexpr);
  }
  $Perlexpr = 'not (' . $Perlexpr . ')' if $v;
  local ($a, $b, $c, $d, $f, $g, $h, $i, $l, $n, $o, $q, $r, $s, $t, $v, $w,
$x, $y,
         $A, $B, $C, $D, $E, $F, $G, $H, $L, $N, $O, $P, $Q, $S, $T, $X, $Y,
$Z);
  eval "\$_ = ''; if ($Perlexpr) {}";

  die "peg: error in Perl expression: $Perlexpr\n", @Warnings, $@ if $@;

} # check_Perlexpr


sub find_files
{
  if ($d && @Files) {
    my ($start_dir, $dir, @dirs, @files);
    foreach (@Files) {
      (-d $_) ? push @dirs, $_ : push @files, $_;
    }
    if ($Dirs_specified = @dirs) {
      @Files = @files;
      require Cwd;
      $start_dir = Cwd::cwd() || die "peg: cannot determine current
directory\n";
      foreach $dir (@dirs) {
        chdir($dir)
          || (($s || print STDERR "peg: can't chdir to $dir: $!\n"), next);
        find($dir);
        chdir($start_dir)
          || die "peg: can't chdir back to starting directory $start_dir:
$!\n";
      }
    }
  }
  find('.') if $r;

  if ([EMAIL PROTECTED] && ($r || ($d && $Dirs_specified)) && !$X) {
    print STDERR "peg: no files found\n" if !$s;
    exit(1);
  }

} # find_files


sub find
{
  my $cwd = shift;
  my (@f, $f, $ff);

  opendir(DIR, '.')
    || (($g || print STDERR "peg: can't opendir $cwd: $!\n"), return);
  @f = readdir DIR;
  closedir DIR;

  foreach $f (@f) {
    next if ($f eq '.' || $f eq '..');
    $ff = "$cwd/$f";
    lstat $f;
    if (-d _) {
      chdir($f)
        || (($g || print STDERR "peg: can't chdir to $ff: $!\n"), next);
      find($ff);
      chdir('..')
        || die "peg: can't chdir back to .. from $ff: $!\n";
    }
    else {
      push @Files, $ff;
    }
  }

} # find


sub help
{
  system("perldoc peg") && die "\npeg: perldoc: $?\n";
  exit;

} # help


sub show_debug
{
  print "peg: Warnings =>\n", @Warnings, "\n" if @Warnings;
  print "peg: Options => ", sort(keys %Options),
    (($_ = $ENV{'PEG_OPTIONS'}) ? " (PEG_OPTIONS = $_)" : ''), "\n\n";
  print "peg: Files =>\n", (map {"\t$_\n"} @Files), "\n";
  print "peg: Perl code =>\n$Eval\n";
  exit;

} # show_debug


sub build_Eval
{
  my ($context, $gap, $nonmatch_print, $output, $print, $reset, @my_vars);

  if ($O) {
    $l = 1;
    $A = $B = $C = $Implicit_C = $c = $L = $q = $Z = 0;
  }
  $No_slurp = @Files = ('-') if ([EMAIL PROTECTED] && !$X);
  $No_slurp ||= $x;
  $C = 1 if ($Implicit_C && !($A || $B));
  $A = $B = 1 if $C;
  $context = $A || $B || $C;
  $c = $l = $L = $q = $S = $Z = 0 if $context;
  $h = 1 if (@Files <= 1 && !(($d && $Dirs_specified) || $r || $X));
  $reset = 1 if (((@Files > 1) || $X) && $Perlexpr =~ /[EMAIL PROTECTED]/ &&
!$x);
  $h = 0 if $H;
  if ($c || $l || $L || $O || $q || $Z) {
    $a = 1;
    $b = $N = $S = $T = 0;
  }
  $y = 1 if (($l || $L || $q) && !$No_slurp);
  $N = 0 if $T;
  $F = 0 if ($F && $Perlexpr !~ /\bF\b/);
  $P = 0 if ($P && $Perlexpr !~ /\bP\b/);
  $a = 1 if $S;

  if ($c) {
    $L = $q = $Z = 0;
  }
  elsif ($L) {
    $q = $Z = 0;
  }
  elsif ($l) {
    $q = $Z = 0;
    $output = '"$File\n"';
    $t = 1;
  }
  elsif ($Z) {
    $q = 0;
  }
  elsif ($q) {}
  else {
    $output = '';
    $output = "\$Offset:" if $b;
    $output = "\$.:$output" if $n;
    $output = "\$File:$output" if !$h;
    $output = "\"$output\$_\"" if $output;
  }

  if (defined $output) {
    $print = 'print' . ($output ? " $output" : '') . ';';
    $print .= ' last;' if ($t && !$context);
  }
  if ($context) {
    $output ||= '$_';
    $gap = ($A ? $After : 0) + ($B ? $Before : 0);
    ($nonmatch_print = $print) =~ s/:/-/g;
    $output =~ s/:/-/g;
    $Perlexpr = "\$First_match && ($Perlexpr)" if $t;
  }

  @my_vars = (($context ? '$After' : ()),
    ($B ? '@Before' : ()),
    ($a ? () : '$Binary_file'),
    ($c ? '$Count' : ()),
    ($F ? '@F' : ()),
    ($context ? '$First_match' : ()),
    '$File',
    ($L ? '$Found' : ()),
    ($b ? '$Length' : ()),
    ($O ? (map {"\$Match$_"} (0..$#Perlexpr)): ()),
    ($context ? '$Matched' : ()),
    ($b ? '$Offset' : ()),
    ($P ? ('$P', '@P') : ()),
    ($Z ? '$Z' : ()));

  $Eval = '';
  $Eval .= "while (<STDIN>) { chomp; push [EMAIL PROTECTED], \$_; }\n" .
           "[EMAIL PROTECTED] || (" . ($s ? '' : '(print STDERR "peg: no files
found\n"), ')
           . "exit(1));\n" if $X;
  $Eval .= "\$| = 1;\n" if !$q;
  $Eval .= ($y ? "undef \$/;\n" : ($Y ? "\$/ = '';\n" : ''));
  $Eval .= "my \$Exit_code = 1;\n" if !$q;
  $Eval .= 'my (' . join(", ", @my_vars) . ");\n";
  $Eval .= "foreach \$File ([EMAIL PROTECTED]) {\n";
  $Eval .= "  open(FILE, \"<\$File\")";
  $Eval .= $s ? " || next;\n"
              : "\n    || ((print STDERR \"peg: can't open \$File:
\$!\\n\"), next);\n";
  $Eval .= "  \$After = $After;\n" if $A;
  $Eval .= "  [EMAIL PROTECTED] = ();\n" if $B;
  $Eval .= "  \$Binary_file = -B FILE;\n" if !$a;
  $Eval .= "  \$Count = 0;\n" if $c;
  $Eval .= "  \$Found = 0;\n" if $L;
  $Eval .= "  \$Offset = 0;\n" if $b;
  $Eval .= "  \$First_match = 1;\n" if $context;
  $Eval .= '  ' . join(" = ", map {"\$Match$_"} (0..$#Perlexpr)) . " = 0;\n"
if $O;
  $Eval .= "  [EMAIL PROTECTED] = ();\n" if $P;
  $Eval .= "  \$Z = '';\n" if $Z;
  $Eval .= "  while (<FILE>) {\n";
  $Eval .= "    \$P = \$_;\n" if $P;
  $Eval .= "    \$Length = length;\n" if $b;
  $Eval .= "    [EMAIL PROTECTED] = split;\n" if $F;
  $Eval .= "    shift [EMAIL PROTECTED] if ([EMAIL PROTECTED] > $Before);\n" if $B;
  $Eval .= "    study;\n" if (@Perlexpr > 5);
  $Eval .= "    if ($Perlexpr) {\n" if !$S;
  $Eval .= '      ' . ($q ? 'exit(0)' : '$Exit_code = 0') . ";\n";
  $Eval .= '      $Binary_file && ((print "Binary file $File matches\n"),
last);' . "\n" if !$a;
  $Eval .= "      $Perlexpr;\n" if $S;
  $Eval .= "      chomp; \$_ .= \"\\n\";\n" if $N;
  $Eval .= "      chomp; \$_ .= ' ';\n" if $T;
  $Eval .= "      ++\$Count;\n" if $c;
  $Eval .= "      \$Found = 1;\n      last;\n" if $L;
  $Eval .= "      print \"--\\n\" if (\$Matched++ && (\$First_match ||
(\$After > $gap)));\n" if $context;
  $Eval .= "      print [EMAIL PROTECTED];\n" if $B;
  $Eval .= "      $print\n" if $print;
  $Eval .= "      \$After = 0;\n" if $A;
  $Eval .= "      [EMAIL PROTECTED] = ();\n" if $B;
  $Eval .= "      \$First_match = 0;\n" if $context;
  $Eval .= "    }\n" if !$S;
  $Eval .= "    elsif (++\$After <= $After) {\n
  $nonmatch_print\n    }\n" if $A;
  $Eval .= "    else {\n" if ($B || ($context && $t));
  $Eval .= "      ++\$After;\n" if (!$A && $B);
  $Eval .= "      push [EMAIL PROTECTED], $output;\n" if $B;
  $Eval .= "      last if !\$First_match;\n" if ($context && $t);
  $Eval .= "    }\n" if ($B || ($context && $t));
  $Eval .= "    \$Offset += \$Length;\n" if $b;
  $Eval .= "    push [EMAIL PROTECTED], \$P;\n" if $P;
  $Eval .= "  }\n";
  $Eval .= '  print "\n";' . "\n" if $T;
  $Eval .= '  print "' . ($h ? '' : '$File:') . '$Count\n";' . "\n" if $c;
  $Eval .= "  chomp \$Z;\n  print \"" . ($h ? '' : '$File:') . "\$Z\\n\";\n"
if $Z;
  $Eval .= '  if (!$Found) { print "$File\n"; }' . "\n" if $L;
  $Eval .= "  reset 'a-z';\n" if $reset;
  $Eval .= "  close FILE;\n}\n";
  $Eval .= 'exit(' . ($q ? '1' : '$Exit_code') . ");\n";

} # build_Eval

__END__

=head1 NAME

peg - Perl expression grep

=head1 SYNOPSIS

peg [<options>|-help] <perlexpr> [<files>]

=head1 DESCRIPTION

Peg is a grep(1) clone. It uses a Perl expressions to match lines
from a list of input files, or standard input if none specified.

Internally, peg eval's code that resembles the following pseudo-Perl:

    foreach $File ( <files> ) {
        open(FILE, "<$File");
        while (<FILE>) {
            if ( <perlexpr> ) {
                print;
            }
        }
    }

Thus, each input line is available as the Perl variable C<$_>, and this
will be printed if <perlexpr> is true. In particular, to match lines
according to a Perl regular expression pattern, it is necessary to place
it within the pattern matching operator, which defaults to searching C<$_>.

  eg% peg '/\bneedle\b/i' haystack

Note that <perlexpr> can be any Perl expression, and is not limited just
to regular expressions.

=head1 OPTIONS

The options include equivalents to most of those of standard grep(1),
including the GNU extensions. They can be grouped anywhere in the
argument list (except after '--'), and can also be set via the
environment variable "PEG_OPTIONS".

If less than two files specified, then B<-h> is assumed.

Selection and interpretation of <perlexpr>:

=over 4

=item B<-E>

Overrides B<-G> & B<-Q>. Assume <perlexpr> is a Perl expression
(this is the default behavior).

=item B<-G>

Assume <perlexpr> is a Perl regular expression pattern to be matched.
This option is implicit if any of B<-i>, B<-w>, B<-x> are used, or if
<perlexpr> matches /^\w+$/ (ie. is entirely alphanumeric). Thus,
"peg foo bar" is equivalent to "peg '/foo/' bar".

=item B<-Q>

Overrides B<-G>. Assume <perlexpr> is a fixed literal string to be matched.
Thus, C<"peg -Q 'fo+' bar"> is equivalent to "peg '/fo\+/' bar".

=item B<-f> <file>

The following argument is a file containing further <perlexpr>'s.
(Note, this is the only option that takes an argument). Lines
will be adjudged to match if they match any of the <perlexpr>'s.

=item B<-o>

Arguments following the B<-o> option up until '--' are interpreted
as further <perlexpr>'s. Lines will be adjudged to match if they
match any of the <perlexpr>'s. For example, C<"peg -o foo bar baz -- file">
is equivalent to C<"peg '/foo/ or /bar/ or /baz/' file">.

=item B<-O>

This option is similar to B<-ol>, except each <perlexpr> must match
independently. As with B<-o>, arguments following the B<-O> option
up until '--' are interpreted as further <perlexpr>'s.

=item B<-i>

Enables B<-G>. Ignore case distinctions.

=item B<-v>

Negates the sense of <perlexpr>.

=item B<-w>

Enables B<-G>. Force <perlexpr> to match only whole words.

=item B<-x>

Enables B<-G>. Force <perlexpr> to match only whole lines.

=back

File selection:

=over 4

=item B<-d>

Any directories listed in the argument list will be searched recursively
for files to work upon.

=item B<-r>

Work upon all files in and beneath the current directory.

=item B<-X>

Interpret STDIN as a stream of filenames to process.
It provides a builtin B<xargs(1)> facility. (See example 6).

=back

Basic output control:

=over 4

=item B<-a>

Do not suppress binary output. The default behavior for when
a match occurs on a binary file is to print "Binary file <filename>
matches".

=item B<-A> B<-B> B<-C> B<-NUM>

These options specify that matching lines should be shown with lines of
surrounding I<context>. B<-A> shows lines of trailing (I<after>) context;
B<-B> shows lines of leading (I<before>) context; B<-C> shows both leading
and trailing context. B<-NUM> sets the number of lines of context for the
most recently specified context option (the default is 2) or assumes B<-C>
if none specified. That is, B<-B1A3> specifies one line of leading context
and three lines of trailing context.

=item B<-b>

Print the byte offset within the input file.

=item B<-c>

Print only a count of the input lines that match <perlexpr>.

=item B<-h>

Suppress filenames being printed when searching multiple files.

=item B<-H>

Print the filename for each match.

=item B<-l>

Print only the names of files which match <perlexpr> at least once.

=item B<-L>

Print only the names of files which don't match <perlexpr> anywhere.

=item B<-n>

Print the input line number.

=item B<-t>

Print only the first match in any one file.

=back

Peg specials:

=over 4

=item B<-D>

Prints out the internal Perl code that would otherwise be eval'ed.

=item B<-F>

Provide an array @F which is the result of a split applied to
the input line.

=item B<-N>

Ensure each printed line ends in a newline. This is only necessary
if <perlexpr> leaves C<$_> without a trailing newline. (See example 2).

=item B<-P>

Provide an array @P of the input up until that point. $P[-1] is the
previous line. This provides a mechanism to allow matches to be made
over consecutive lines. (See example 4).

=item B<-S>

Always print the input line. This enables stream editing with s///.

=item B<-T>

Print each file's output on one single line, with each line separated
by a single whitespace.

=item B<-y>

Treat each file as a single line.

=item B<-Y>

Treat paragraphs (text delimited by blank lines) as single lines.

=item B<-Z>

Print the value of $Z at EOF. (See example 5).

=back

Miscellaneous:

=over 4

=item B<-g>

Suppress the error messages about unreadable directories outputted
when either B<-d> or B<-r> is used.

=item B<-q>

Write nothing to STDOUT. Exit 0 if a match is found, else exit 1.

=item B<-s>

Suppress all error messages about unreadable files and directories.

=item B<-V>

Display peg's version number and exit.

=item B<-->

Explicitly end options. Allows filenames beginning with a -.
Also used by the B<-o> and B<-O> options to determine which arguments are
<perlexpr>'s and which are files.

=back

=head1 EXAMPLES

  1. Search recursively for all VHDL constant declarations:

    % peg -r '/^\s*constant\s.*:=/i'

  2. Find the instance names of CTS buffers in a verilog netlist:

    % peg -N '/^\s*CTS\w*\s+(\w+)\s*\(/ and $_ = $1' foo.v

  3. Extract the entity declaration section from a VHDL file:

    % peg 's/\s*--.*$//, /^\s*entity\b/i .. /^\s*end\b/i' bar.vhd

  4. Search for the sequence A,B,C split over 3 consecutive lines:

    % peg -PB2n '$P[-2]=~/A/ and $P[-1]=~/B/ and /C/' bam

  5. Sum up the entries in the last column of a file:

    % peg -ZF '$Z += $F[-1]' report.txt

  6. Search for "main" in C files below the current directory.

    % find . -name "*.c" | peg -Xw main

=head1 ENVIRONMENT

The environment variable PEG_OPTIONS can be used to set options.

=head1 EXIT STATUS

The following exit values are returned:

  0            one or more matches were found
  1            no matches were found
  >1           peg did not complete normally

=head1 SCRIPT CATEGORIES

Search

=head1 README

This script is yet another Perl grep(1).

=head1 SEE ALSO

L<perl(1)>, L<perlre>, L<grep(1)>.

=head1 AUTHOR

Alex Davies <[EMAIL PROTECTED]>

=head1 COPYRIGHT

Copyright (c) 1999 Alex Davies. All rights reserved. This program is
free software; you can redistribute it and/or modify it under the same
terms as Perl itself.

=cut



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

Reply via email to