Using sed to pattern match within a particular multiline block and take action

Hi all,
This is my first post, so please go easy if I broke some rules. Not accustomed to posting in forums... :slight_smile:

I'm looking for help on pattern matching within a multiline block and looking to highlight blocks/block-ids that do NOT contain a particular pattern.

For example an input file might contain the following:

fruit APPLE
   blah1
   PATTERN
   blah2
fruitend

fruit ORANGE
blah1
blah2
blah3
fruitend

fruit KIWI
PATTERN
blah1
blah2
fruitend

In the above case, I would like the block of ORANGE or the keyword ORANGE printed, since the recognized pattern was not found.

I've been playing around with this for a while with no desired results found!! :slight_smile:

sed -n '
/fruit /,/fruitend/ {H;g;s/\n//g;}
/PATTERN/ !p;
/fruit /,/fruitend/ !h;
'

Those results are the closest I can get to what I really want of:

    fruit ORANGE

being the only listed output.

I figured out another way to do it, but was hoping to do it in one sed. I figured out if I pipe it through another sed statement like this:

<PREVIOUS OUTPUT>  | sed -n 's/fruit \([A-Z]*\).*fruitend/\1/p'

That will print ORANGE only.

If the are empty lines between the records, you could try:

awk '!/PATTERN/' RS= infile
1 Like

With sed, try this:

sed -n '/^$/b blk;H;$b blk;b;:blk;x;s/\n//;/PATTERN/!P' <file

--
Bye

1 Like

Hey Guys... thanks for the replies so far.
I'm sorry that I forgot to mention that there are no blanks in between. So yeah it makes it a little more hairy. I was trying to break it apart into a bunch of easy tasks as I built out what I had gotten to so far. I'll check some of those suggestions out tomorrow out and tinker with commands to try to figure it out again tomorrow. (I'll repost if I figure something out).

Thanks,
Bobby

A quick solution might be to introduce the blank lines in an extra step:

awk '$1=="fruit"{print x}1' infile | awk '!/PATTERN/' RS=
sed -n '/fruitend/b blk;H;$b blk;b;:blk;x;s/^\(fruitend\)*\n//;/PATTERN/!P' <file

--
Bye