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 comocontinueenC.nextsuprime 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,awktiene su propiawhile