-
-
Save torson/bd6931bda0035c4884b2a8c4c64a33b2 to your computer and use it in GitHub Desktop.
A basic perl implementation of grep switches : -A , -B , -v , -P, -i
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
# NOTE1: this script works only with stdin/pipe so use it like 'cat FILE | grep.pl -P ...' | |
# NOTE2: -A and -B features don't mix well if matching lines are in cross section | |
## this is a basic implementation of grep switches : -A , -B , -v , -P, -i | |
# reason: Mac doesn't support "grep -P" | |
# > OS X's grep changed from grep (GNU grep) 2.5.1 in 10.7 to grep (BSD grep) 2.5.1-FreeBSD in 10.8 | |
# -- https://stackoverflow.com/questions/16658333/grep-p-no-longer-works-how-can-i-rewrite-my-searches | |
## sample oneliners that were used before making of this script | |
# - equivalent to 'grep -P "PATTERN"' | |
# perl -e'while(<>){if( (m!PATTERN!) ){$ok++;print}};if(!($ok)){exit 1}' | |
# - equivalent to 'grep -P -i "PATTERN"' | |
# perl -e'while(<>){if( (m!PATTERN!i) ){$ok++;print}};if(!($ok)){exit 1}' | |
# - equivalent to 'grep -v -P "PATTERN"' | |
# perl -e'while(<>){if( !(m!PATTERN!) ){$ok++;print}};if(!($ok)){exit 1}' | |
# basic algorithm from here: https://www.perlmonks.org/?node_id=779717 | |
use strict; | |
use warnings; | |
my $linesA = ""; | |
my $linesB = ""; | |
my $inverse = ""; | |
my $ignoreCase = ""; | |
my $regex = ""; | |
my $inErr = ""; | |
my $err = ""; | |
my $help = ""; | |
$help .= "\nWRONG ARGUMENT INPUT! Exiting.."; | |
$help .= "\n\nUsage:\n$0 OPTIONS\n\nOPTIONS:\n"; | |
$help .= "\n\t-P=REGEX"; | |
$help .= "\n\t-v"; | |
$help .= "\n\t-A=NUM ; -A and -B don't mix well if matching lines are in cross section"; | |
$help .= "\n\t-B=NUM ; -A and -B don't mix well if matching lines are in cross section"; | |
$help .= "\n\nEXAMPLE: \n\tcat FILE | $0 -A=5 -v -P='^ *#' ; print following 5 lines where the grepped line is not a comment"; | |
$help .= "\n\n"; | |
## ARGUMENTS FETCH | |
for (my $iargv=0; $iargv<=$#ARGV; $iargv++) { | |
my @param; | |
if ($ARGV[$iargv] =~ m/^\-A\=/i) { | |
@param = split(/=/, $ARGV[$iargv]); | |
$linesA=$param[1]; | |
} | |
elsif ($ARGV[$iargv] =~ m/^\-B\=/i) { | |
@param = split(/=/, $ARGV[$iargv]); | |
$linesB=$param[1]; | |
} | |
elsif ($ARGV[$iargv] =~ m/^\-v$/i) { | |
$inverse = 1; | |
} | |
elsif ($ARGV[$iargv] =~ m/^\-i$/i) { | |
$ignoreCase = 1; | |
} | |
elsif ($ARGV[$iargv] =~ m/^\-P\=/i) { | |
@param = split(/=/, $ARGV[$iargv]); | |
$regex=$param[1]; | |
} | |
else { | |
print $help; | |
exit; | |
} | |
} | |
if (scalar(@ARGV)==0) { | |
$inErr .= "\n Error! No input arguments. \n"; | |
} | |
if ($inErr ne "") { | |
print $inErr . "\n" .$help; | |
exit; | |
} | |
my ($prev, $next); | |
my @aLinesA; | |
my @aLinesB; | |
my $lineCount=0; | |
my $matchedLinesCount=0; | |
while (my $line = <STDIN>) { | |
$lineCount++; | |
if ( $linesA && $next ) { | |
print "$line"; | |
# print "linesA=$linesA , next=$next \n"; | |
if ( $next >= $linesA ) { | |
$next = undef; | |
} | |
else { | |
$next++; | |
} | |
} | |
if ($inverse) { | |
if ($ignoreCase) { | |
if ( $line !~ m/$regex/i ) { | |
$matchedLinesCount++; | |
if (defined( $prev )) { | |
# print @aLinesB; | |
# print "prev=$prev\n"; | |
# print "--\n"; | |
for (my $i=$#aLinesB-$linesB+1 ; $i<=$#aLinesB ; $i++) { | |
print "$aLinesB[$i]"; | |
} | |
} | |
$prev = undef; | |
@aLinesB=(); | |
print "$line"; | |
if (!($next)) { | |
$next++; | |
} | |
} | |
} | |
else { | |
if ( $line !~ m/$regex/ ) { | |
$matchedLinesCount++; | |
if (defined( $prev )) { | |
# print @aLinesB; | |
# print "prev=$prev\n"; | |
# print "--\n"; | |
for (my $i=$#aLinesB-$linesB+1 ; $i<=$#aLinesB ; $i++) { | |
print "$aLinesB[$i]"; | |
} | |
} | |
$prev = undef; | |
@aLinesB=(); | |
print "$line"; | |
if (!($next)) { | |
$next++; | |
} | |
} | |
} | |
} | |
else { | |
if ($ignoreCase) { | |
if ( $line =~ m/$regex/i ) { | |
$matchedLinesCount++; | |
if (defined( $prev )) { | |
# print @aLinesB; | |
# print "prev=$prev\n"; | |
# print "--\n"; | |
for (my $i=$#aLinesB-$linesB+1 ; $i<=$#aLinesB ; $i++) { | |
print "$aLinesB[$i]"; | |
} | |
} | |
$prev = undef; | |
@aLinesB=(); | |
print "$line"; | |
if (!($next)) { | |
$next++; | |
} | |
} | |
} | |
else { | |
if ( $line =~ m/$regex/ ) { | |
$matchedLinesCount++; | |
if (defined( $prev )) { | |
# print @aLinesB; | |
# print "prev=$prev\n"; | |
# print "--\n"; | |
for (my $i=$#aLinesB-$linesB+1 ; $i<=$#aLinesB ; $i++) { | |
print "$aLinesB[$i]"; | |
} | |
} | |
$prev = undef; | |
@aLinesB=(); | |
print "$line"; | |
if (!($next)) { | |
$next++; | |
} | |
} | |
} | |
} | |
if ( $linesB ) { | |
$prev++; | |
push(@aLinesB, $line); | |
} | |
} | |
if (!($matchedLinesCount)) { | |
exit 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment