Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

For example, from this file:

CREATE SYNONYM I801XS07 FOR I8010.I801XT07
               *
ERROR at line 1:
ORA-00955: name is already used by an existing object


CREATE SYNONYM I801XS07 FOR I8010.I801XT07
               *
ERROR at line 1:
ORA-00955: name is already used by an existing object



Table altered.


Table altered.


Table altered.


Table altered.


Table altered.


Table altered.


Table altered.


Table altered.

DROP INDEX I8011I01
           *
ERROR at line 1:
ORA-01418: specified index does not exist



Index created.

I want a way to find ORA- and show the ORA- line and the previous 4 lines:

CREATE SYNONYM I801XS07 FOR I8010.I801XT07
               *
ERROR at line 1:
ORA-00955: name is already used by an existing object

CREATE SYNONYM I801XS07 FOR I8010.I801XT07
               *
ERROR at line 1:
ORA-00955: name is already used by an existing object

DROP INDEX I8011I01
           *
ERROR at line 1:
ORA-01418: specified index does not exist
share|improve this question

3 Answers 3

up vote 4 down vote accepted

Supposing you're on an elderly system, like HP-UX, that doesn't have GNU utilities, just the old, original BSD or AT&T "grep". You could do something like this:

#!/bin/sh

awk '/ORA-/ { print line1; print line2; print line3; print line4; print $0 }\
// {line1 = line2; line2 = line3; line3 = line4; line4 = $0}' $1

Yes, there's tons of edge conditions this doesn't get right, but whatta ya want for nothing? Also, given that you're working on some decroded, antiquated OS and hardware, you probably don't have the CPU horsepower for fancy error handling.

share|improve this answer
    
Works Perfect For me. Thanks a lot –  Javier Ortega Oct 14 '11 at 12:31
awk 'NR == FNR && $0 ~ p {
  for (i = FNR; i >= FNR - l; i--)
    nr[i]; next
  }
FNR in nr  
BEGIN {
  ARGV[ARGC++] = ARGV[ARGC - 1]
  }' l=4 p=ORA- infile   

On Solaris use nawk or /usr/xpg4/bin/awk.

share|improve this answer

The -B option to grep does exactly that: grep -B 4 ORA- your_file.

In the absence of GNU grep, I've adapted the grep4 example from the grymoire sed tutorial:

#!/bin/sh

# grepB4: prints out 4 lines before and the line including pattern
# if there is only one argument, exit

case $# in 
    1);;
    *) echo "Usage: $0 pattern";exit;;
esac;

sed -n '
'/"$1"/' !{
    # does not match - add this line to the hold space
    H
    # bring it back into the pattern space
    x
    # Two lines would look like .*\n.*
    # Three lines look like .*\n.*\n.*
    # Delete extra lines - keep four
    s/^.*\n\(.*\n.*\n.*\n.*\)$/\1/
    # put it back in hold space
    x
}
'/"$1"/' {
    # matches - append the current line
    H
    # bring hold space contents into pattern space
    g
    # print the 4 lines
    p
    # add the mark
    a\
---
}'

Usage: grepB4 pattern < file.

Bruce Ediger's answer does essentially the same thing with awk, which often has less cryptic syntax than sed.

share|improve this answer
1  
As far as I know this option is only present in GNU grep. The Solaris one doesn't. –  rahmu Oct 11 '11 at 14:49
    
HP-UX Release 11i: grep -B 4 ORA- I8010.LOG grep: illegal option -- B –  Javier Ortega Oct 11 '11 at 15:28

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.