From the first hi to the first hello that follows.
Using (GNU) grep and tr:
$ <infile grep -oPz "(?s)hi.*?hello" | tr '\0' '\n'
hi aa bb cc
dd ee ff
hi aaa bbb
<infile Source file.
grep -oPz Call
-P) match a PCRE (Perl Compatible Regular Expression)
-o) only print the matching part.
-z) use a zero byte (a.k.a. NUL and a.k.a.
\0) as line delimiter.
"(?s) Make the PCRE dot (
.) match also newlines.
hi Starting with the string
.*? Match all characters that follow (non-greedy because of
hello" Up until the string
hello is matched.
| tr '\0' '\n' Convert the NULs (
\0) bytes (from
grep -z) to newlines.
<infile sed 's/hi/\n&/;s/[^\n]*\n//;s/\(hello\).*/\1/;/hi/,/hello/!d'
Or, for BSD sed, which doesn't allow
\n on the right side of
s///, you need to define a
$ eval "$(printf "nl='\n'")"
<infile sed 's/hi/\'"$nl"'&/;s/[^\n]*\n//;s/\(hello\).*/\1/;/hi/,/hello/!d'
Or; if you could write an explicit newline:
<infile sed 's/hi/\