Text Processing - Obtenha 2 linhas com texto exato entre elas

1

Eu tenho um arquivo com número desconhecido de blocos de texto que consistem em iniciar a palavra-chave "Iniciar", terminar a palavra-chave "Fim" e texto opcional entre eles com uma palavra-chave exata "Disco" em cada linha e preciso me livrar dos onde não há nada entre eles, veja o exemplo.

Estou processando entrada assim:

Server1:Start
Server1:End
Server2:Start
Disk1
Disk2
Server2:End
Server3:Start
Disk1
Server3:End

, e minha saída desejada é esta:

Server2:Start
Disk1
Disk2
Server2:End
Server3:Start
Disk1
Server3:End

Eu sei que posso usar 'awk' ou 'sed' para encontrar texto entre duas linhas, mas não sei o que fazer, se houver várias ocorrências dessas duas linhas ou se não houver texto entre elas 2 linhas.

Estou executando o Ubuntu 17.10.

Esperando ansiosamente por qualquer ajuda.

Editar: eu apaguei a primeira vez do post, porque eu pensei que eu poderia fazer isso usando sed -e '/Start/,/End/d' , mas isso realmente remove tudo.

    
por mikro45 14.01.2018 / 19:19

2 respostas

2

Para excluir% de volta para trás, Start e End linhas, isso deve ser feito no GNU sed:

$ sed -e '/Start/ {N; /^\(.*\):Start\n:End$/d }' < input

se virmos Start , carregue a próxima linha com N e, em seguida, veja se o conteúdo do buffer é apenas Somename:Start\nSomename:End com Somename same nas duas linhas ( \n é uma nova linha). Em caso afirmativo, exclua-o. Aqui, é uma referência ao primeiro grupo dentro de \(..\) e corresponde à mesma sequência que foi encontrada lá. .* significa apenas qualquer número ( * ) de qualquer caractere ( . ).

Usar sed -e '/Start/,/End/d' de fato excluiria todas as linhas, já que o intervalo corresponde a todas as linhas entre os padrões inicial e final. Tudo na entrada está entre Start e End , então tudo é excluído.

    
por 14.01.2018 / 21:39
1

outra solução, como eu gosto de tentar fazer isso no awk.

BEGIN { 
    RS="End\n"
    ORS="End\n"
} 
NF > 2

usando o RS ou a variável do separador de registro, o awk tratará entre cada End\n como um registro, e presumindo que servername:Start e servername:End sejam palavras únicas, é apenas um caso de impressão linhas com mais de 2 campos através da linha NF > 2 . Se isso for verdade, a linha inteira será impressa, com End\n usado como separador de registro de saída ( ORS )

~$>echo '
Server1:Start
Server1:End
Server2:Start
Disk1
Disk2
Server2:End
Server3:Start
Disk1
Server3:End
' | awk 'BEGIN { RS="End\n"; ORS="End\n"; } NF > 2;'
Server2:Start
Disk1
Disk2
Server2:End
Server3:Start
Disk1
Server3:End
    
por 18.01.2018 / 00:23