tags:

views:

494

answers:

5
+2  Q: 

Advanced grep unix

Usually grep command is used to display the line contaning the specified pattern. Is there any way to display n lines before and after the line which contains the specified pattern?

Can this will be achieved using awk?

+8  A: 

Yes, use

grep -B num1 -A num2

to include num1 lines of context before the match, and num2 lines of context after the match.

EDIT:

Seems the OP is using AIX. This has a different set of options which doesn't include -B and -A

this link describes grep on AIX 4.3 (it doesn't look promising)

Matt's perl script might be a better solution.

pavium
It not working on my systrmgrep -B 3 -A 2 sunny sachingrep: illegal option -- BUsage: grep -hblcnsviw pattern file . . .
Sachin Chourasiya
I am working on AIX.
Sachin Chourasiya
I have retagged the question. I hope an AIX expert comes along.
pavium
A: 

Sure there is (from the grep man page):

   -B NUM, --before-context=NUM
          Print  NUM  lines  of  leading  context  before  matching lines.
          Places  a  line  containing  a  group  separator  (--)   between
          contiguous  groups  of  matches.  With the -o or --only-matching
          option, this has no effect and a warning is given.

   -A NUM, --after-context=NUM
          Print NUM  lines  of  trailing  context  after  matching  lines.
          Places   a  line  containing  a  group  separator  (--)  between
          contiguous groups of matches.  With the  -o  or  --only-matching
          option, this has no effect and a warning is given.

and if you want the same amount of lines before AND after the match, use:

   -C NUM, -NUM, --context=NUM
          Print NUM lines of output context.  Places a line  containing  a
          group separator (--) between contiguous groups of matches.  With
          the -o or --only-matching option,  this  has  no  effect  and  a
          warning is given.
Puppe
Its not there for AIX , and my apologies I havent mentioned that this problem is on AIX.
Sachin Chourasiya
Check my other answer, it should work for AIX, since AIX supports -n argument.
Puppe
Can we have something standard or a combination of awk for this
Sachin Chourasiya
@Sachin, have you tried my awk solution then?
ghostdog74
+1  A: 

From the tags, it's likely that the system has a grep that may not support providing context (Solaris is one system that doesn't and I can't remember about AIX). If that is the case, there's a perl script that may help at http://www.sun.com/bigadmin/jsp/descFile.jsp?url=descAll/cgrep%5F%5Fcontext%5Fgrep.

Matt
A: 

If you have sed you could use this shell script

BEFORE=2
AFTER=3
FILE=file.txt
PATTERN=pattern
for i in $(grep -n $PATTERN $FILE | sed -e 's/\:.*//')
  do head -n $(($AFTER+$i)) $FILE | tail -n $(($AFTER+$BEFORE+1))
done

What it does is, grep -n prefixes each match with the line it was found at, the sed strips all but the line it was found at. Then you use head to get the lines up to the line it was found on plus an additional $AFTER lines. That's then piped to tail to just get $BEFORE + $AFTER + 1 lines (that is, your matching line plus the number of lines before and after)

Puppe
A: 

you can use awk

awk 'BEGIN{t=4}
c--&&c>=0
/pattern/{ c=t; for(i=NR;i<NR+t;i++)print a[i%t] }
{ a[NR%t]=$0}
' file

output

$ more file
1
2
3
4
5
pattern
6
7
8
9
10
11

$ ./shell.sh
2
3
4
5
6
7
8
9
ghostdog74
Yes, I tried but it wont work, getting an error awk: syntax error near line 1awk: bailing out near line 1
Sachin Chourasiya
use nawk if you have it.
ghostdog74