Want to grep for a pattern and display the content above that pattern

Hi,
When we have a failure, sometimes we just step restart the job from the next step. Later when we open the log for analysis of the failure, it is becoming difficult to go to the failure part.
For eg., if it is a 1000 line log, the failure may be at 500th line. so wat i want to do is, grep for the FAIL word and shud be able to see the content above that, only 50-60 lines.

xxxxxx
xxxxxx
xxxxxx
ODS FAILED
xxxxxx
xxxxx
xxxxx

I want the lines above that ODS FAILED.

Pls help me with this.

Thanks
Ajay

Something like this:

 
awk 'c&&c--;/FAILED/{c=50;print p;exit}{p=p"\n"$0}' log_file

Forget to say : this is suggested by one of this forum member some time back ( few months).

with GNU grep (Linux)

grep -B 60 'ODS FAILED'  logfile

For everywhere else here is one way:

grep -n 'ODS FAILED' logfile | awk -F":" '{print $1; exit}' | read ln
start=$(( $ln - 50 ))
[[ $start -le 0 ]]  && start=1
sed -n "$start,$ln,p" logfile

Hi,
Thanks for your replies, but they dint work :frowning:

@panyam: It is displaying all the lines before that. i did a wc -l and here is the output
[cmg-iqdps2p0] x772525 /usr/prod/bdw/log> awk 'c&&c--;/FAILED/{c=50;print p;exit}{p=p"\n"$0}' dm_distwatch10r.20100624.log|wc -l
621

@jim mcnamara: It is throwing an error
ksh: start=-50[[: This is not an identifier.

$ perl -nle 'if (!/FAIL/) { push @x, $_; }
             else { push @x, $_; for ( $#x-50 .. $#x ) { print $x[$_] } @x=(); }' infile

Edit: This ^^ will misbehave if there are less than 50 lines before the pattern FAIL, here's the fix:

$ perl -nle 'if (!/FAIL/) { push @x, $_; }
else { push @x, $_;
if ($#x > 50) {
for ( $#x-50 .. $#x ) { print $x[$_] } @x=(); }
else { for ( 0 .. $#x ) { print $x[$_] }} @x=(); }' infile

Sorry , misread it.

Something like this:

  
awk '/FAILED/{print p;exit} {p=p"\n"$0}' input_file | tail -50

Thanks all for your replies. It is working now :slight_smile: