Here you go..
I can't remember where I found this, but it works really well.
Code:
#!/usr/bin/perl
#
# wgrep.pl - windowed grep utility
#
# Change Log
#----------------------------------------------------------------
# 13/11/2006 - Goran Script Created
#
use strict;
use IO::File;
use IO::Handle;
my ($before,$after,$show_stars,$show_nums,$sep,$show_fname);
my ($show_sep,$arg,$file,$regexp,$lnum,$fhandle,$nbef,$naft);
my ($matched,$matched2,@line_buf,@temp,$fh,$ret);
$before = 3; $after = 3; # default window size
$show_stars = 0;
$show_nums = 0;
$sep = "**********\n";
$show_fname = 1;
$show_sep = 1;
# loop until an argument doesn't begin with a "-"
while ($ARGV[0] =~ /^-(\w)(.*)/) {
$arg = $1; # $arg holds the option letter
if ($arg eq "s") { $show_stars = 1; }
elsif ($arg eq "n") { $show_nums = 1; }
elsif ($arg eq "m") { $show_fname = 0; }
elsif ($arg eq "d") { $show_sep = 0; }
elsif ($arg eq "w") {
# parse 2nd matched section at colon
@temp=split(/:/,$2);
$before = $temp[0] if $temp[0] ne '';
$after = $temp[1] if $temp[1] ne '';
}
elsif ($arg eq "p") {
$before = 0;
$after = 0;
$show_sep = 0; }
elsif ($arg eq "W") {
$before = 0;
$after = 0;
}
elsif ($arg eq "h") { &usage(""); }
else { &usage("wgrep: invalid option: $ARGV[0]");
} # end of if command
shift; # go on to next argument
} # end of foreach loop
&usage("wgrep: missing regular expression") if ! $ARGV[0];
$regexp = $ARGV[0];
shift;
$regexp =~ s,/,\\/,g; # "/" --> "\/"
# if no files are specified, use standard input
if (! @ARGV[0]) { @ARGV[0] = "STDIN"; }
LOOP:
foreach $file (@ARGV) { # loop over file list
if ($file eq "STDIN") {
$fh=new IO::Handle;
$ret=$fh->fdopen(fileno(STDIN),"r");
die "Can't open STDIN." unless $ret;
}
else {
$fh = new IO::File "$file", "r";
if (! defined $fh) {
print STDERR "Can't open file $file; skipping it.\n";
next LOOP; # jump to LOOP label
}
}
$lnum = 0;
$nbef = 0; $naft = 0;
$matched = 0; $matched2 = 0;
&clear_buf(0) if $before > 0;
while (<$fh>) { # loop over the lines in the file
++$lnum; # increment line number
if ($matched) { # we're printing the match window
if ($_ =~ /$regexp/) { # if current line matches pattern:
$naft = 0; # reset the after window count,
&print_info(1); # print preliminary stuff,
print $_; # and print the line
}
else { # current line does not match
if ($after > 0 && ++$naft <= $after) {
# print line anyway if still in the after window
&print_info(0); print $_;
}
else { # after window is done
$matched = 0; # no longer in a match
$naft = 0; # reset the after window count
# save line in before buffer for future matches
push(@line_buf, $_); $nbef++;
} # end else not in after window
} # end else curr. line not a match
} # end if we're in a match
else { # we're still looking for a match
if ($_ =~ /$regexp/) { # we found one
$matched = 1; # so set match flag
# print file and/or section separator(s)
print $sep if $matched2 && $nbef > $before && $show_sep && $show_fname;
print "********** $file **********\n" if ! $matched2++ && $show_fname;
# print and clear out before buffer and reset before counter
&clear_buf(1) if $before > 0; $nbef = 0;
&print_info(1);
print $_; # print current line
}
elsif ($before > 0) {
# pop off oldest line in before buffer & add current line
shift(@line_buf) if $nbef >= $before;
push(@line_buf,$_); $nbef++;
} # end elseif before window is nonzero
} # end else not in a match
} # end while loop over lines in this file
$fh->close;
} # end foreach loop over list of files
exit; # end of script proper
# subroutines #
sub print_info {
print $_[0] ? "* " : " " if $show_stars;
printf "%4d ", $lnum if $show_nums;
} # end subroutine print_info
sub clear_buf {
# argument says whether to print before window or not
my ($i,$j,$print_flag);
$print_flag = $_[0];
$i = 0; $j = 0;
if ($print_flag) {
# if we're printing line numbers, fiddle with the
# counter to account for the before window
if ($show_nums) {
$lnum -= ($#line_buf + 1);
}
while ($j <= $#line_buf) { # print before window
&print_info(0);
print $line_buf[$j++];
$lnum++ if $show_nums;
} # end while
} # end if print_flag
@line_buf = (); # clear line_buf array
} # end subroutine clear_buf
sub usage {
# optional argument is an additional message line
print STDERR $_[0],"\n" if $_[0];
print STDERR "Usage: wgrep [-n] [-w[B][:A] | -W] ";
print STDERR "[-d] [-p] [-s] [-m] regexp file(s)\n";
print STDERR " -n = number lines\n";
print STDERR " -s = mark matched lines with asterisks\n";
print STDERR " -wB:A = display B lines before and A lines after\n";
print STDERR " each matched line [both default to 3]\n";
print STDERR " -W = suppress window; equivalent to -w0:0\n";
print STDERR " -d = suppress separation lines between sections\n";
print STDERR " -m = suppress file name header lines\n";
print STDERR " -p = plain mode: equivalent to -W -d\n";
print STDERR " -h = print this help message and exit\n";
print STDERR "Note: If present, -h prevails; otherwise, the rightmost\n";
print STDERR " option wins in the case of contradictions.\n";
exit;
}
Hey Guys,
Wondering if there is a way to do the following
I have a file called test.txt
abc
def
abc
abc
def
I have a pattern file called pattern.txt containing the following
abc
def
I want to do a count, but have it display the count value preceeding each line like grep -n (2 Replies)
I have a file from which I need to collect lines to another file. I know how to use 'grep' for this, but I don't know how to do when I wan't several lines after the search word, and the amount of lines I need varies from case to case.
The file I search in looks something like this:
>8534734... (9 Replies)
Hello,
How do I use grep to find a pattern in a list of file and then display 5 lines after the pattern is matched
Eg:
I want to match the string GetPresentCode in all files in a folder and then see 4 lines following this match. I am not sure if grep is what should be used to achieve. Thanks!... (3 Replies)
I have to grep on a few words in a file and then display the line containing those words and the line above it.
For ex -
File1.txt contains...
abc xyz abc
This is a test
Test successful
abc xyz abc
Just a test
Test successful
I find the words 'Test successful' in the file... (6 Replies)
Hello everyone.
I would like to know if I can use grep or zgrep to search for a particular pattern then print the x number of lines after the pattern was found.
Lets say for example a pattern was found on line 3, I wanted the output to show lines 3, 4 and 5.
Thanks! (10 Replies)
Hi,
I wanted to grep string "ERROR" and "WORNING" after last occurrence of String "Starting" only and wanted to display two lines after searched ERROR and WORNING string and one line before. I have following cronjob log file "errorlog" file and I have written the code for same in Unix as below... (17 Replies)
Hi,
Need help to grep the following from a file x. I just want to grep exact match not lines and not partial word.
CONFSUCCESS
CONFFAIL
CONFPARTIALSUCCESS
>cat x
xczxczxczc zczczcxx CONFSUCCESS czczczcczc
czxxczxzxczcczc CONFFAIL xczxczcxcczczc
zczczczcz CONFPARTIALSUCCESS czczxcxzc
... (4 Replies)
Hi I need to grep for a patter and display all lines below the pattern.
For ex: say my file has the below lines
file1
file2
file3
file4
file5
I NEED to grep for patter file3 and display all lines below the pattern. do we have an option to get this data. Let me know if you require... (5 Replies)
Hi guys,
I have a log file that generates multiple logs about a query.
<query time='2016-04-13 13:01:50.825'>
<PagingRequestHandler>
<Before>brand:vmu</Before>
<After>brand:vmu</After>
</PagingRequestHandler>
<GroupDeviceFilterHandler>
<Before>brand:vmu</Before>
... (3 Replies)
hi,
I have a log file with data for more than 3 years, i want only the rows for the year 2017, say for example.
My file has the data like this
08-OCT-2015 11:17:35 AAA, BBBB
08-OCT-2017 11:17:35 AAA,Bdfdfd,dfdfd,dfd
08-Nov-2017 11:17:35 AAA,Bdfdfd,dfdfd,deree
i want the rows... (2 Replies)