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 comocontinueemC.nextsuprime 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,awktem sua própriawhile