Digamos que tengo un archivo:
PRO 1 GLN 5.55112e-17 ILE -6.245e-17 THR 5.55112e-17
Quiero que cada línea que tenga un número diferente a 1 en la segunda columna lo cambie a 0 y mantenga el resto.
Si uso if
(es decir declaración condicional), todo está bien:
awk "{if($2!=1){print $1,"0"}else{print $0}}" file PRO 1 GLN 0 ILE 0 THR 0
Pero cuando uso el bloque condicional, sucede algo no deseado:
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
Puede ver lo que está mal.
- ¿Cómo soluciono este error?
- ¿Por qué ocurre este error?
- ¿Cuál es la diferencia entre una declaración condicional y un bloque condicional?
Responder
En una if
declaración, tiene una else
. Si if
no coincide, se ejecuta la rama else
.
En una declaración condicional, ambas acciones son ejecutado, independientemente de que la condición sea verdadera o falsa.
Una solución simple:
$ awk "$2!=1 {print $1,"0";next};{print $0}" file PRO 1 GLN 0 ILE 0 THR 0
Y puede hacerlo más conciso:
$ awk "$2 != 1 {print $1,"0";next};1" file PRO 1 GLN 0 ILE 0 THR 0
Cuando la condición es verdadera 1
y no hay acción, awk
el comportamiento predeterminado es print
. print
sin argumento se imprimirá $0
de forma predeterminada.
Comentarios
Respuesta
El segundo bloque en
awk "$2!=1 {print $1,"0"} {print $0}" file
no es condicional. Se actúa sobre él para cada línea y, por lo tanto, imprime cada línea.
En su lugar, escriba:
awk "$2!=1 {print $1,"0"} $2==1 {print $0}" file
O escriba:
awk "$2!=1 {print $1,"0"; next} {print $0}" file
Esto hará que se omita el bloque incondicional, si el bloque condicional coincide.
awk '$2!=1?$2=0:"";1' file
.next
. Supongo que suprime la segunda impresión si la primera es verdadera. Algo comocontinue
enC
.next
suprime el procesamiento de la línea de entrada actual, pase a la siguiente. La misma función quewhile
, pero para todo el programaawk
. Además,awk
tiene su propiawhile