Excluir texto entre parênteses, mas nunca depois da linha vazia

0

Considere um arquivo de texto, com linhas de texto reunidas em vários blocos, em que cada bloco é separado por pelo menos uma linha vazia. Usando um one-liner do Bash, como excluo todo o texto de < para > ou \n\n ?

Em outras palavras: exclua tudo entre cada par de < e > . Se < não tiver fechamento > , exclua tudo até o final do bloco (uma linha vazia), mas nunca, nunca delete fora do bloco!

Conceitualmente, devo separar fisicamente os blocos em objetos em uma lista antes de analisar por segurança, ou este é um trabalho de análise de texto linear direto, desde que você saiba o que está fazendo?

Exemplo de texto:

This is the first
block of text.
                             <-- empty line
<delete me>
This is the second block.
<delete
here>
<delete this, but
                             <-- empty line
do not delete this>
<delete this too>
Third block here.

(more blocks)

O resultado deve ser:

This is the first
block of text.
                             <-- empty line
This is the second block.
                             <-- empty line
do not delete this>
Third block here.
    
por forthrin 07.04.2018 / 12:15

2 respostas

1

Tente o modo de parágrafo do awk:

$ awk -v RS= -v ORS='\n\n' '{gsub(/<[^>]+>?\n?/, "")}1' ip.txt 
This is the first
block of text.

This is the second block.


do not delete this>
Third block here.
  • -v RS= isto fará com que uma ou mais linhas vazias consecutivas sejam usadas como separador de registro de entrada
  • -v ORS='\n\n' definiu o separador de registro de saída como dois caracteres de nova linha
  • gsub(/<[^>]+>?\n?/, "") delete < seguido por non > caracteres seguidos por > e caracteres de nova linha opcionais
  • 1 maneira idiomática de imprimir o conteúdo dos registros de entrada


Mesma coisa com perl

perl -00 -lpe 'BEGIN{$\="\n\n"} s/<[^>]+>?\n?//g' ip.txt
    
por 07.04.2018 / 15:18
0
Solução

GNU Awk :

awk -v RS='[<>]' '/\n\n/{ sub(/^[^\n]+\n/, ""); print $0 RT }' file
  • RS='[<>]' - trata < e > como separador de registro
  • /\n\n/ - se o registro atual contiver 2 quebras de linha:
    • sub(/^[^\n]+\n/, "") - remova tudo até a primeira nova linha (inclusive)
    • print $0 RT - imprime o registro atual seguido por RT (ou seja, > )
    • RT - o terminador de registro. Gawk define RT para o texto de entrada que correspondeu ao caracter ou expressão regular especificado por RS .

A saída:

<empty line>   
don't delete this>
    
por 07.04.2018 / 13:07