sed problem - delete all lines until a match on 2 lines

First of all, I know this can be more eassily done with perl or other scripting languages but, that's not the issue. I need this in sed. (or wander if it's possible )

I got a file (trace file to recreate the control file from oracle for the dba boys)
which contains

some lines
another line
...
STARTUP NOMOUNT
some lines
another line
...
a line ending with ;
STARTUP NOMOUNT
some lines
another line
...
a line ending with ;

The file contains also some lines in comment in between the others. These lines start with '#'

I want the part from the first "STARTUP NOMOUNT" untill the line before the second "STARTUP NOMOUNT" in 1 file and the part from the second "STARTUP NOMOUNT" untill the end in another file.

I know how to do this in ksh and I guess I would quickly find a solution in perl also but, now it's time to sharpen my sed skills :slight_smile:

I already gor this

sed '/^STARTUP NOMOUNT/,/^STARTUP NOMOUNT/!d' ikke | sed '/^#/d' | sed '$d'

This will delete all the lines except those between the 2 occurences on "STARTUP NOMOUNT", next it will delete the lines in comment and finally it will delete the last line which is the second occurence of "STARTUP NOMOUNT". So, this gives me already 1 file with the first part.

But, how do I get the second part ?

I already tried

sed '/^STARTUP NOMOUNT/,$!d' ikke | sed '/^#/d' | sed '1,/^STARTUP NOMOUNT/d'

But, this deletes 1 line too many

Anyone an idea ?

I couldnt get your question very clearly...

If you give input and expected output, it would be useful for us.

Simply with awk:

awk '/STARTUP NOMOUNT/{i++}i{print > "file_" i}' infile

Franklin52,
nice trick, can you give some explication ?
Having the code is nice but, I would like to understand it also :slight_smile:
This makes it eassier to build on if other situations should occure

By the way, do you know a way to do this with sed ?

The awk code is very good. I modified it to not print the comments, as I think you had indicated you don't want those to print, should they show up between the STARTUP NOMOUNT and the line with the ";".

 
awk '/STARTUP NOMOUNT/{i++} i && $1 !~ /^#/ {print > "file_" i}' infile

To get the second section with sed you can first delete the first section with:

sed '/STARTUP NOMOUNT/,/STARTUP NOMOUNT/!d' ikke > temp

Get the second section:

sed -n '/STARTUP NOMOUNT/,/STARTUP NOMOUNT/p' temp > file2

With sed it's much more complicated then awk, so I think awk is *the* tool for such tasks:

awk '/STARTUP NOMOUNT/{i++}i{print > "file_" i}' infile

Explanation:

/STARTUP NOMOUNT/{i++}

If the pattern is match we increase a counter i

i{print > "file_" i}

If i is true (not 0) print the current line to the file file_i

Regards

sed -n `grep -n <reg_pattern> <filename> | head -2 | cut -d":" -f1`,`wc -l <filename> | cut -d" " -f1`p <filename>

This is for your satisfaction,.... this would work fine but not recommended... ppl hav given ideal solutions

Hi Franklin,

Thank you. But i cant understand the procedure how this command gives the output :mad:.

once the string "STARTUP NOMOUNT" matches from the input file i value will get increased to 1. After that how its printing the next lines upto the next match.

That is how this command prints the 2,3 lines also in file_1 file(output file)
Please explain

Example for the input file:
-------------------------
STARTUP NOMOUNT
test_file
text
STARTUP NOMOUNT

Thanks in advance,

It's quite simple, maybe this is more understandable:

/STARTUP NOMOUNT/{i++} # If the line matches the pattern then i = i + 1
i{print > "file_" i} # If i is not 0 print the line to the file "file_i"

After the first match the lines are printed to the file file_1 (i == 1), after the second match (i == 2) the lines are printed to the file file_2 (i == 2) etc.

Regards

resetting the value of "i" to zero(0) did not happen... that is why it prints all the lines between regular expression...

Hi thank a lot folks, now i understood

thank you all for the valuable help
know_d_unknown, you proved my case that this is feasable with sed (so, I won 12 beers from one of my colleaugues :slight_smile: )
but I also agree that the solution of franklin is the best one