How to grep lines between start and end pattern?

grep won't help you here. This is a job better accomplished with sed using range expressions:

$ sed -n '/aaa/,/cdn/p' file
aaa
b12
cdn
$ sed -n '/zdk/,/dke/p' file
zdk
aaa
b12
cdn
dke

sed -n suppresses the automatic printing, so that lines are printed just if explicitly asked to. And this happens when the range /aaa/,/cdn/ happens.

These range expressions are also available in awk, where you can say:

awk '/zdk/,/dke/' file

Of course, all these conditions can be expanded to a more strict regex like sed -n '/^aaa$/,/^cdn$/p' file to check that the lines consist on exactly aaa and cdn, nothing else.


It can be done by sed

sed -n '
    /^aaa$/,/^cdn$/w output1
    /^zdk$/,/^dke$/w output2
    ' file

Here is grep command:

grep -o "aaa.*cdn" <(paste -sd_ file) | tr '_' '\n'

You can achieve multiline match in grep, but you need to use perl-regexp for grep (-P - which is not supported on every platform, like OS X), so as workaround we're replacing new lines with _ character and after grep, we're changing them back.

Alternatively you can use pcregrep which supports multi-line patterns (-M).

Or use ex:

ex +"/aaa/,/cdn/p" -scq! file