exclusão seletiva de linhas entre dois padrões

exclusão seletiva de linhas entre dois padrões

Eu tenho um arquivo que contém o seguinte conteúdo,

Hello world Unix!!
Its bright world
Current time is HH:mm:ss
Next action plan is item #3
End of task.
Thank you.


Hello world Linux!!
All actions completed.
End of Activity.
Thanks.

Gostaria de excluir seletivamente todas as linhas que contêm a palavra-chave "mundo" e também todas as linhas subsequentes até que uma linha com um conjunto específico de palavras-chave (exemplo, "Atividade" ou "tarefa") seja encontrada.

Saída desejada:

End of task.
Thank you.
End of Activity.
Thanks. 

Responder1

Tentar:

$ awk  -v f=1 '/world/{f=0} /Activity|task/{f=1} f' File
End of task.
Thank you.


End of Activity.
Thanks.

Como funciona:

  1. -v f=1

    Crie uma variável awk fe defina-a como 1.

  2. /world/{f=0}

    Se a linha atual contiver world, defina a variável fcomo zero.

  3. /Activity|task/{f=1}

    Se a linha contiver Activityou task, defina fcomo 1.

    Observe que worldacima e Activityou taskaqui são tratados como expressões regulares. Além disso, eles diferenciam maiúsculas de minúsculas.

  4. f

    Se ffor diferente de zero, imprima a linha.

Para excluir também linhas em branco

$ awk  -v f=1 '/world/{f=0} /Activity|task/{f=1} f && /./' File
End of task.
Thank you.
End of Activity.
Thanks.

f && /./diz ao awk para imprimir a linha somente se ffor diferente de zeroea linha contém pelo menos um caractere (de qualquer tipo).

Responder2

Não é tão bonito quanto a solução awk, mas como o OP marcou a pergunta comsedtambém, aqui vai:

#with blank lines
sed '/world/,/task\|Activity/{//!d};/world/d' file

#without blank lines
sed '/world/,/task\|Activity/{//!d};/world\|^$/d' file

Observe o uso de //, que significa a expressão regular anterior usada :)

informação relacionada