Skip to content

Instantly share code, notes, and snippets.

@torson

torson/grep.pl Secret

Created February 10, 2022 20:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save torson/bd6931bda0035c4884b2a8c4c64a33b2 to your computer and use it in GitHub Desktop.
Save torson/bd6931bda0035c4884b2a8c4c64a33b2 to your computer and use it in GitHub Desktop.
A basic perl implementation of grep switches : -A , -B , -v , -P, -i
#!/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