Eu tenho um arquivo como abaixo.
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
~PAR2~
This is Par2 line 1
This is Par2 line 2
Par Finished
Se eu passar PAR1
, devo obter todas as linhas entre PAR1
e Par Finished
linha. Como posso conseguir? Estava pesquisando awk
e sed
não encontrei nenhuma opção.
Responder1
Se você quiser a linha de cabeçalho e rodapé, é bem simples, por sed
exemplo
sed -n "/^~PAR1~$/,/Par Finished/p"
Isso é simples de usar com uma variável
START=PAR1
sed -n "/^~$START~$/,/Par Finished/p"
Também podemos fazer com que a última linha seja uma variável
START=PAR1
END="Par Finished"
sed -n "/^~$START~$/,/$END/p"
O resultado é semelhante a:
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
Agora, se você não quer as linhas de início/fim e não quer a linha em branco, então é um pouco mais complicado.
Pode haver maneiras melhores, mas isso funciona para mim:
sed -n "/^~$START~$/,/$END/ { /^~$START~$/d ; /$END/d ; /^$/d ; p }"
O resultado disso é
This is Par1 line 1
This is Par1 line 2
Responder2
Você pode usar a Par Finished
linha (com linhas em branco opcionais) como separador de registros (e substituí-la para completar o registro)
awk -vRS='\nPar Finished\n*' -vp='PAR1' '$0 ~ p {print $0,"\nPar Finished"}' parfile
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
Se você tiver GNU
o awk, poderá recuperar o separador de registros com a variável especial RT
(removendo as novas linhas extras, se desejar)
gawk -vRS='\nPar Finished\n*' -vp='PAR1' '$0 ~ p {sub("\n*$", "", RT); print $0,RT}' parfile
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
Claro que se você não precisa passar por umvariável Par1
você usa um intervalo de regex simples
awk '/PAR1/,/Par Finished/' parfile
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
Responder3
Com grep
e pcre
para entrada de arquivo suficientemente pequena
$ s="PAR1"
$ grep -oPz "(?s)[^\n]*${s}.*?\n.*?Par Finished.*?\n" ip.txt
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
Para obter linhas entre o padrão:
$ grep -oPz "(?s)${s}.*?\n\K.*?(?=Par finalizado)" ip.txt Esta é a linha 1 do Par1 Esta é a linha 2 do Par1
Alterando variável paraPAR2
$s="PAR2" $ grep -oPz "(?s)${s}.*?\n\K.*?(?=Par finalizado)" ip.txt Esta é a linha Par2 1 Esta é a linha Par2 2
Referência: Regex (grep) para pesquisa multilinha