I want to write a shell script so that it selects a pattern from a file and copies only that part. In this file I have to search for "Errors" pattern. If this is present I must check if it contains "ORA" in the subsequent line. If this is present then I have to copy from a line previous to the "Errors" line till the next date.
How can this be accomplished. Can anyone Help?

LQ is a volunteer-driven community effort relying on its members to supply answers if and when they want to. If you need on-demand 24/7 coverage, please consider hiring a local Linux guru, else just be patient.

Wed Sep 5 23:32:42 2007
Errors in file /home/oracle10/admin/EAIDB/bdump/eaidb_j000_17397.trc:
ORA-12012: error on auto execute of job 8874
ORA-20000: ORA-20000: Content of the tablespace specified is not permanent or tablespace name is invalid
ORA-06512: at "SYS.PRVT_ADVISOR", line 1624
ORA-06512: at "SYS.DBMS_ADVISOR", line 186
ORA-06512: at "SYS.DBMS_SPACE", line 1338
ORA-06512: at "SYS.DBMS_SPACE", line 1554

Thanks JSCHIWAL. But I could not understand the program can u help me out with it? Also it should print only if both Errors and ORA patterns are found assuming that in the file there are line which has only ORA patterns also. How do I modify the same for that. The file is as follows.

checks if the term "Errors" is in the record (the block between each Mon-Sun found) If it's found it runs the code.

Code:

{for(i=1;i<=NF;i++){
if ($i~/^ORA/) {
print rt$0;rt=RT;next}

loops from 1 to NF (number of fields). Basically it's scanning all fields, checks if the field starts with ORA. if it does it prints the the whole record and goes to the "next" one.

Code:

rt=RT

I did this because RT= record terminator, so it would give me the name that matched the end of the record, not the start. So I just copy the RT to rt as i scan, and insert rt (the one from the previous record) before my printout.

I hope it makes sense enough for you to figure out.

PS:
You can add something like

Code:

ORS='-------------\n'

if it'll help you with readability of the output.
here's the output using your second sample as a source:

[quote=sagarbsa;2912509]Thanks JSCHIWAL. But I could not understand the program can u help me out with it?

Code:

$ sed -r '/(Mon|Tue|Wed|Thu|Fri|Sat|Sun)/i\ # Matches lines starting with a date, and inserts a blank line before it. This makes selecting a range easier.
' junk | sed -rn '/(Mon|Tue|Wed|Thu|Fri|Sat|Sun)/,/^$/{ # Selects a single section at a time. Inside a bracket, you can have pattern tests for lines in between.
/^$/!H # If this isn't a blank line (end of the range), then add this line to the Hold buffer.
/^$/{ # At the end of the pattern, so check if the patter 'ORA' exists. If so, yank back the Hold buffer and print it out.
x # exchange the current working buffer (blank) with the Hold buffer. This both recalls the lines from the hold buffer and clears the hold buffer.
/ORA/p # print out the lines.
}
}'

I don't see any lines in the sample set that contain an error.
Since we used the "H" command, the working register contains multiple lines, so the pattern
from both lines of input are present and can be tested for.