sed - Print lines matched by a pattern range if one line matches a condition

$ sed -n '/--START--/{:a;N;/--END--/!ba; /Device=A/p}' file
--START--
Device=A
Data=asdfasdf
Lorem=Ipsum
--END--
--START--
Device=A
Data=asdfasdf
--END--

(The above was tested on GNU sed. It would have to be massaged to run on BSD/OSX.)

How it works:

  • /--START--/{...}

    Every time we reach a line that contains --START--, run the commands inside the braces {...}.

  • :a

    Define a label a.

  • N

    Read the next line and add it to the pattern space.

  • /--END--/!ba

    Unless the pattern space now contains --END--, jump back to label a.

  • /Device=A/p

    If we get here, that means that the patterns space starts with --START-- and ends with --END--. If, in addition, the pattern space contains Device=A, then print (p) it.


Other sed variant with hold space use

sed 'H              #add line to hold space
     /--START--/h   #put START into hold space (substitute holded in)
     /--END--/!d    #clean pattern space (start next line) if not END
     x              #put hold space into pattern space
     /Device=A/!d   #clean pattern space if it have not "Device=A"
    ' file