How to search for keywords in subsequent lines

Hi all,
I am looking for a coomand to search for the keywords in susequenct lines. Keyword1 in a line and Keyword2 in the very next line.
Once i found the combination ineed to print the lines with patterns and the line above and one below.

I am giving an example here: Keywords are :ERROR and Found Path

Input data :

aaaaaaaa bbbbbbbbb vvvvvvvv
(:ERROR)  ccccccccc dddddddddddd eeeeeeeee kkkkk
Found Path: rrrrrr bbbb
cccccccccccc vvvvvvvvvvv kkkk rrrrrrrrr
aaaaaaaa bbbbbbbbb vvvvvvvv fffffffff 
(:ERROR)  aaaaaaaaaaa bnbbbbbbbbbbb ccccccc
ggggggggg hhhhhhhhhhhhhh rrrrrrrr
xxxxxxxxxx yyyyyyyyyyyyy zzzzzzzzzzzz
(:ERROR)  rrrrrrrrrrrr ssssssss tttttttt
Found Path: ggghhhhh sshshshshs
pppppppppp qqqqqqqq rrrrrrrrrrr

Output expected:

aaaaaaaa bbbbbbbbb vvvvvvvv
(:ERROR)  ccccccccc dddddddddddd eeeeeeeee kkkkk
Found Path: rrrrrr bbbb
cccccccccccc vvvvvvvvvvv kkkk rrrrrrrrr
xxxxxxxxxx yyyyyyyyyyyyy zzzzzzzzzzzz
(:ERROR)  rrrrrrrrrrrr ssssssss tttttttt
Found Path: ggghhhhh sshshshshs
pppppppppp qqqqqqqq rrrrrrrrrrr

As a start here you have the code to get the lines that have both patterns following up including the subsequent lines.
To get the line above and below these blocks you can give a try yourself maybe. But I guess someone comes up with a complete solution soon :wink:

$> awk '/^\(:ERROR\)/ { a=$0; getline; if($0 ~ /^Found Path:/) {print a"\n"$0; z=1} else{z=0; next} } z==1 && !/^Found Path/ {print}' z=0 infile
(:ERROR)  ccccccccc dddddddddddd eeeeeeeee kkkkk
Found Path: rrrrrr bbbb
cccccccccccc vvvvvvvvvvv kkkk rrrrrrrrr
aaaaaaaa bbbbbbbbb vvvvvvvv fffffffff
(:ERROR)  rrrrrrrrrrrr ssssssss tttttttt
Found Path: ggghhhhh sshshshshs
pppppppppp qqqqqqqq rrrrrrrrrrr

Try this:

awk '/(:ERROR)/{err=$0;getline;if($0 ~ /^Found Path/){print prev RS err RS $0;getline; print}}{prev=$0}' file

Regards

Save the below code say get_output

#!/usr/bin/awk -f
BEGIN {
        prev_line_text=$0;
        next_line_of_error=0;
        cur_line=0
        error_found_line_no=cur_line;
        found_path_line_no=cur_line;
        }

        {
                cur_line++;
        }

!/ERROR/ && !/Found Path/ {
                if ( (found_path_line_no - error_found_line_no ) ==  1 )
                {
                        printf( "%s\n%s\n%s\n%s\n", prev_line_text, found_error_text, found_path_text, $0);
                }
                prev_line_text=$0;
                error_found_line_no=cur_line;
                found_path_line_no=cur_line;
        }
/ERROR/ {
        found_error_text=$0;
        next_line_of_error=1;
        error_found_line_no=cur_line;
        }

!/ERROR/ && /Found Path/ {
            if ( (error_found_line_no + 1 ) == cur_line )
            {
                found_path_text=$0;
                found_path_line_no=cur_line
            }
        }

run the script as get_output <input file_name>.

I did a quick check it is working.. Let us me know if any one know better approach then this.

Thank you all for the inputs.

Franklin52, your code is working perfectly.

Apart from printing,Can i have the code for the deleteion of those lines from the input file?

Redirect the output to another file and replace the original file with it:

awk '..' file > newfile
mv newfile file

Franklin52, I need the details of the lines with pattern,next line and the line above in a seperate file. For that i am re-directing the output of the command you provided.

Also need the remaining file, once we seperate the details mentioned above.

Regardingyour command, it doesn't print the the line above the first occurrence of the sequence.

Output expected is

---------- Post updated at 08:04 AM ---------- Previous update was at 08:03 AM ----------

aaaaaaaa bbbbbbbbb vvvvvvvv
(:ERROR)  ccccccccc dddddddddddd eeeeeeeee kkkkk
Found Path: rrrrrr bbbb
cccccccccccc vvvvvvvvvvv kkkk rrrrrrrrr
xxxxxxxxxx yyyyyyyyyyyyy zzzzzzzzzzzz
(:ERROR)  rrrrrrrrrrrr ssssssss tttttttt
Found Path: ggghhhhh sshshshshs
pppppppppp qqqqqqqq rrrrrrrrrrr

first line is not coming with your code.Please help

I get the desired output with my code:

$ cat file
aaaaaaaa bbbbbbbbb vvvvvvvv
(:ERROR)  ccccccccc dddddddddddd eeeeeeeee kkkkk
Found Path: rrrrrr bbbb
cccccccccccc vvvvvvvvvvv kkkk rrrrrrrrr
aaaaaaaa bbbbbbbbb vvvvvvvv fffffffff 
(:ERROR)  aaaaaaaaaaa bnbbbbbbbbbbb ccccccc
ggggggggg hhhhhhhhhhhhhh rrrrrrrr
xxxxxxxxxx yyyyyyyyyyyyy zzzzzzzzzzzz
(:ERROR)  rrrrrrrrrrrr ssssssss tttttttt
Found Path: ggghhhhh sshshshshs
pppppppppp qqqqqqqq rrrrrrrrrrr
$ awk '/(:ERROR)/{err=$0;getline;if($0 ~ /^Found Path/){print prev RS err RS $0;getline; print}}{prev=$0}' file
aaaaaaaa bbbbbbbbb vvvvvvvv
(:ERROR)  ccccccccc dddddddddddd eeeeeeeee kkkkk
Found Path: rrrrrr bbbb
cccccccccccc vvvvvvvvvvv kkkk rrrrrrrrr
xxxxxxxxxx yyyyyyyyyyyyy zzzzzzzzzzzz
(:ERROR)  rrrrrrrrrrrr ssssssss tttttttt
Found Path: ggghhhhh sshshshshs
pppppppppp qqqqqqqq rrrrrrrrrrr

Am I missing something?

Sorry, That was my mistake. Your code works well.
Can you please give me the code for removing the above code's output from the file? So that i can work on the remaining data

expected output is

aaaaaaaa bbbbbbbbb vvvvvvvv fffffffff 
(:ERROR)  aaaaaaaaaaa bnbbbbbbbbbbb ccccccc
ggggggggg hhhhhhhhhhhhhh rrrrrrrr

The second output is print to the file new_output.

awk '
/(:ERROR)/{
  err=$0;getline
  if($0 ~ /^Found Path/){
     print prev RS err RS $0;getline; print
     next
  } else {
    print prev RS err RS $0 > "new_output"
  }
}
{prev=$0}
' file > newfile
mv newfile > file

Regards

Thanks a lot. It worked perfectly.

---------- Post updated 08-11-09 at 04:18 AM ---------- Previous update was 08-10-09 at 10:13 AM ----------

Hello Franklin52,

Need an update in the code that you have provided.. Currently it is only considering the lines with keyword ERROR to start the search. In fact there are some lines in teh data without keywords ERROR and Found Path. I need those lines to be remained in the main file once we separate the lines with Pattern. Could you please re-look into this?

input data

aaaaaaaa bbbbbbbbb vvvvvvvv
(:ERROR)  ccccccccc dddddddddddd eeeeeeeee kkkkk
Found Path: rrrrrr bbbb
cccccccccccc vvvvvvvvvvv kkkk rrrrrrrrr
aaaaaaaa bbbbbbbbb vvvvvvvv fffffffff
(:ERROR)  aaaaaaaaaaa bnbbbbbbbbbbb ccccccc
ggggggggg hhhhhhhhhhhhhh rrrrrrrr
xxxxxxxxxx yyyyyyyyyyyyy zzzzzzzzzzzz
(:ERROR)  rrrrrrrrrrrr ssssssss tttttttt
Found Path: ggghhhhh sshshshshs
pppppppppp qqqqqqqq rrrrrrrrrrr
rrrrrrrrrrrr ssssssss tttttttt
Found Path: ggghhhhh sshshshshs
pppppppppp qqqqqqqq rrrrrrrrrrr
rrrrrrrrrrrr ssssssss tttttttt
Found Path: ggghhhhh sshshshshs
pppppppppp qqqqqqqq rrrrrrrrrrr

output1

aaaaaaaa bbbbbbbbb vvvvvvvv
(:ERROR)  ccccccccc dddddddddddd eeeeeeeee kkkkk
Found Path: rrrrrr bbbb
cccccccccccc vvvvvvvvvvv kkkk rrrrrrrrr
xxxxxxxxxx yyyyyyyyyyyyy zzzzzzzzzzzz
(:ERROR)  rrrrrrrrrrrr ssssssss tttttttt
Found Path: ggghhhhh sshshshshs
pppppppppp qqqqqqqq rrrrrrrrrrr

Out put2(remaing file after the data seperated to output1)

aaaaaaaa bbbbbbbbb vvvvvvvv fffffffff
(:ERROR)  aaaaaaaaaaa bnbbbbbbbbbbb ccccccc
ggggggggg hhhhhhhhhhhhhh rrrrrrrr
rrrrrrrrrrrr ssssssss tttttttt
Found Path: ggghhhhh sshshshshs
pppppppppp qqqqqqqq rrrrrrrrrrr
rrrrrrrrrrrr ssssssss tttttttt
Found Path: ggghhhhh sshshshshs
pppppppppp qqqqqqqq rrrrrrrrrrr

You can use the first command to produce the first file and grep to get the other lines:

grep -v -f output1 inputdata

I am getting the below error. Not sure if it is supported under SunOS box. Can you suggest me an alternative?

grep: illegal option -- f