Do primeiro olá ao primeiro olá que segue.
grep
Usando (GNU) grep e tr:
$ <infile grep -oPz "(?s)hi.*?hello" | tr '<infile sed 's/hi/\n&/;s/[^\n]*\n//;s/\(hello\).*//;/hi/,/hello/!d'
' '\n'
hi aa bb cc
dd ee ff
hello
hi aaa bbb
ccc hello
Descrição:
-
<infilearquivo de origem. -
grep -oPzChamegreppara:- (
-P) corresponde a um P CRE (expressão regular compatível com Perl) - (
-o) o simplesmente imprima a peça correspondente. - (
-z) usa um z ero byte (também conhecido como NUL e a.k.a.) como delimitador de linha."(?s)
- (
-
.Faça com que o ponto PCRE (hi) coincida com as novas linhas. -
hiComeçando com a string.*?. -
?Coincidir com todos os caracteres que seguem (não gananciosos por causa dehello"). -
helloAté a string| tr 'ser correspondida.' '\n'grep -z -
\nConverte os bytes NULs (s///) (denewline) em novas linhas.
sed
GNU sed:
$ eval "$(printf "nl='\n'")"
Ou, para o BSD sed, que não permite nl no lado direito de %code% , você precisa definir um %code% variable %code% :
<infile sed 's/hi/\'"$nl"'&/;s/[^\n]*\n//;s/\(hello\).*//;/hi/,/hello/!d'
E então:
<infile sed 's/hi/\
&/;s/[^\n]*\n//;s/\(hello\).*//;/hi/,/hello/!d'
Ou; se você pudesse escrever uma nova linha explícita:
$ <infile grep -oPz "(?s)hi.*?hello" | tr '<infile sed 's/hi/\n&/;s/[^\n]*\n//;s/\(hello\).*//;/hi/,/hello/!d'
' '\n'
hi aa bb cc
dd ee ff
hello
hi aaa bbb
ccc hello