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:
-
<infile
arquivo de origem. -
grep -oPz
Chamegrep
para:- (
-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. -
hi
Começando com a string.*?
. -
?
Coincidir com todos os caracteres que seguem (não gananciosos por causa dehello"
). -
hello
Até a string| tr '
ser correspondida.
' '\n'grep -z
-
\n
Converte 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