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:
-v f=1
Crie uma variável awk
f
e defina-a como1
./world/{f=0}
Se a linha atual contiver
world
, defina a variávelf
como zero./Activity|task/{f=1}
Se a linha contiver
Activity
outask
, definaf
como1
.Observe que
world
acima eActivity
outask
aqui são tratados como expressões regulares. Além disso, eles diferenciam maiúsculas de minúsculas.f
Se
f
for 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 f
for 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 :)