#
# Programname: fpg - Frams' Perl grep
# Author: framstag@rus.uni-stuttgart.de
-# Copyright: GPL
+# Licence: Perl Artistic
#
# History:
# 2003-02-27 Framstag initial version
# 2003-02-28 Framstag added exit status
# 2007-03-09 Framstag added option -Q
-# 2007-06-01 Framstag added options -s and -c
+# 2007-06-01 Framstag added options -s and -c
# and changed default output mode
# 2007-06-03 Framstag added ReadLine-support
# 2007-08-31 Framstag added option -x
# -n ==> -S, new -n option
# 2008-10-14 Framstag added option -M
# 2008-11-23 Framstag added option -~
+# 2016-06-12 Framstag option -o respects (match)
use Getopt::Std;
use Term::ReadLine;
use locale;
-sub usage {
- die <<EOD
+$0 =~ s:.*/::;
+$| = 1;
+
+$usage = <<EOD;
usage: $0 [options] 'EXP' [file...]
or: $0 [options] -Q file...
-options: -r recursively scan through directories
+options: -r recursively scan through directories
-i ignore case
-v print only lines that do NOT match
-s verbose scanning/searching
-l list filenames only
-L list filenames only that do NOT match
-p show paragraphs, not lines (multiline record separator)
- -o show only matched strings, not whole lines
+ -o show only matched strings (in parenthesis), not whole lines
-M mail-mode: search and show complete mails from mbox files
-c print (count) only number of matches (NOT LINES!)
-F EXP is a string, not a Perl regular expression
#examples: $0 -r 'from.*STDIN' *
# $0 -e 'length>30 and not /\\w/' script
#See "perldoc perlre" for help on regular expressions.
-}
-$0 =~ s:.*/::;
-$| = 1;
$maxlen = 0;
$opt_x = $opt_X = '';
$opt_R = "\n";
-usage() if !getopts('hirvlLFMopscQen~S:R:C:x:X:') or $opt_h and not @ARGV;
+getopts('hirvlLFMopscQen~S:R:C:x:X:') or die $usage;
+
+if ($opt_h) {
+ print $usage;
+ exit;
+}
unless ($opt_Q) {
- $exp = shift or usage();
+ $exp = shift or die $usage;
}
if ($opt_C and ($opt_l or $opt_L or $opt_s or $opt_v or $opt_p or $opt_M)) {
$opt_XX = 0;
if (not ${'opt_~'}) {
@bfiles = grep(/~$|^#.*#$/,@ARGV);
- if (@bfiles and
+ if (@bfiles and
(grep(/[^~]$/,@ARGV) or grep(/(^|\/)#[^\/]*#$/,@ARGV))) {
$opt_XX = 1;
warn "$0: ignoring @bfiles\n"; # unless $opt_r;
if ($opt_p) { $/ = '' }
else { $/ = $opt_R }
#else { eval '$/ = "'.$opt_R.'"' }
-
+
$opt_h = 1 if not $opt_r and @ARGV < 2;
if ($opt_Q) {
} else {
$exp =~ s/([\@\$\%\^\&\*\(\)\+\[\]\{\}\\\|\.\?])/\\$1/g if $opt_F;
$exp = '(?i)'.$exp if $opt_i;
- $exp = '(?s)'.$exp if $opt_p or $opt_R;
+ $exp = '(?s)'.$exp if $opt_p or $opt_R ne "\n";
#? $exp =~ s/\.\*\*/[.\n]*/g;
}
-
+
$found = 0;
-
+
if (@ARGV) {
foreach $file (@ARGV) {
next if $opt_X and $file =~ /$opt_X/;
my $dir = shift;
my $file;
my $found = 0;
-
+
opendir $dir,$dir or return;
while (defined($file = readdir $dir)) {
next if $file eq '.' or $file eq '..';
}
next unless -f $file or -c $file or -S $file or -p $file or -z $file;
$fileq = quotemeta $file;
- if (-T $file and open $file,$file or
+ if (-T $file and open $file,$file or
open $file,"strings -a -n $opt_S $fileq|") {
$found += grepf($file,$file);
close $file;
my $file = shift;
my $found = 0;
my ($n,$l,$c);
-
+
warn $B."scanning $file".$N."\n" if -t STDOUT and $opt_s;
-
+
while (<$F>) {
$_ .= "\n" unless /\n$/;
if ($opt_M) {
$C{0} = [$l,$_];
}
if ($opt_e) {
- if ($opt_v) {
+ if ($opt_v) {
next if &$egrep;
- } else {
+ } else {
unless (&$egrep) {
if ($opt_C and $c) {
print "$l:" if $opt_n;
if ($opt_Q) { $n++ while /$exp/mg }
else { $n++ while /$exp/omg }
} else {
- if ($opt_o) {
- my $m = '';
- while (s/($exp)//) {
- $n++;
- $m .= "$1\n";
+ if ($opt_o) {
+ if ($exp =~ /\([^?]+\)/) {
+ if (/$exp/) {
+ $n++;
+ $_ = "$1\n";
+ }
+ } else {
+ my $m = '';
+ while (s/($exp)//) {
+ $n++;
+ $m .= "$1\n";
+ }
+ $_ = $m;
}
- $_ = $m;
- } elsif ($opt_Q) {
+ } elsif ($opt_Q) {
$n += s/($exp)/$B$1$N/mg;
- } else {
+ } else {
$n += s/($exp)/$B$1$N/omg;
}
}
$file = '';
}
if ($opt_x and $n) {
- if ($opt_i) { s/($opt_x)/$B$1$N/ogi }
+ if ($opt_i) { s/($opt_x)/$B$1$N/ogi }
else { s/($opt_x)/$B$1$N/og }
}
for (my $i=$opt_C;$i;$i--) {
$L{$l} = $l;
$c = $opt_C;
}
-
+
if ($opt_c) {
print "$file:" if @ARGV>1;
print "$found\n";