Digamos que eu tenha um arquivo:
PRO 1 GLN 5.55112e-17 ILE -6.245e-17 THR 5.55112e-17
Quero que cada linha com um número diferente de 1 na segunda coluna mude para 0 e mantenha o resto.
Se eu usar if
(ou seja, declaração condicional), está tudo OK:
awk "{if($2!=1){print $1,"0"}else{print $0}}" file PRO 1 GLN 0 ILE 0 THR 0
Mas quando uso o bloco condicional, algo indesejável acontece:
awk "$2!=1 {print $1,"0"} {print $0}" file PRO 1 GLN 0 GLN 5.55112e-17 ILE 0 ILE -6.245e-17 THR 0 THR 5.55112e-17
Você pode ver o que está errado.
- Como faço para corrigir esse erro?
- Por que esse erro ocorre?
- Qual é a diferença entre uma declaração condicional e um bloco condicional?
Resposta
Em um if
declaração, você tem uma else
. Se if
não corresponder, o else
branch é executado.
Em uma instrução condicional, ambas as ações são executado, independentemente de a condição ser verdadeira ou falsa.
Uma solução simples:
$ awk "$2!=1 {print $1,"0";next};{print $0}" file PRO 1 GLN 0 ILE 0 THR 0
E você pode torná-lo mais conciso:
$ awk "$2 != 1 {print $1,"0";next};1" file PRO 1 GLN 0 ILE 0 THR 0
Quando a condição for verdadeira 1
e não houver ação, awk
o comportamento padrão é print
. print
sem nenhum argumento imprimirá $0
por padrão.
Comentários
Resposta
O segundo bloco em
awk "$2!=1 {print $1,"0"} {print $0}" file
não é condicional. Ele é executado em cada linha e, portanto, imprime cada linha.
Em vez disso, escreva:
awk "$2!=1 {print $1,"0"} $2==1 {print $0}" file
Ou escreva:
awk "$2!=1 {print $1,"0"; next} {print $0}" file
Isso fará com que o bloco incondicional seja pulado, se o bloco condicional for correspondido.
awk '$2!=1?$2=0:"";1' file
.next
. Acho que suprime a segunda impressão se a primeira for verdadeira. Algo comocontinue
emC
.next
suprime o processamento da linha de entrada atual, pule para a próxima. A mesma função dewhile
, mas para todo o programaawk
. Além disso,awk
tem sua própriawhile