Si at jeg har en fil:
PRO 1 GLN 5.55112e-17 ILE -6.245e-17 THR 5.55112e-17
Jeg vil at hver linje som har et tall som ikke er lik 1 i andre kolonne, skal endre det til 0 og beholde resten.
Hvis jeg bruker if
(dvs. betinget uttalelse), alt er OK:
awk "{if($2!=1){print $1,"0"}else{print $0}}" file PRO 1 GLN 0 ILE 0 THR 0
Men når jeg bruker den betingede blokken, skjer det noe uønsket:
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
Du kan se hva som er galt.
- Hvordan løser jeg denne feilen?
- Hvorfor oppstår denne feilen?
- Hva er forskjellen mellom en betinget uttalelse og en betinget blokk?
Svar
I en if
uttalelse, du har en else
. Hvis if
ikke stemmer overens, blir else
-grenen utført.
I en betinget uttalelse er begge handlinger utført, uansett om tilstanden er sann eller usann.
En enkel løsning:
$ awk "$2!=1 {print $1,"0";next};{print $0}" file PRO 1 GLN 0 ILE 0 THR 0
Og du kan gjøre det mer kortfattet:
$ awk "$2 != 1 {print $1,"0";next};1" file PRO 1 GLN 0 ILE 0 THR 0
Når tilstanden er sann 1
og det ikke er noen handling, awk
standardadferd er print
. print
uten argument vil $0
skrives ut som standard.
Kommentarer
Svar
Den andre blokken i
awk "$2!=1 {print $1,"0"} {print $0}" file
er ikke betinget. Den blir fulgt opp for hver linje, og skriver dermed ut hver linje.
Skriv i stedet:
awk "$2!=1 {print $1,"0"} $2==1 {print $0}" file
Eller skriv:
awk "$2!=1 {print $1,"0"; next} {print $0}" file
Dette vil føre til at den ubetingede blokken hoppes over, hvis den betingede blokken samsvares.
awk '$2!=1?$2=0:"";1' file
.next
. Jeg antar at det undertrykker den andre utskriften hvis den første er sant. Noe somcontinue
iC
.next
undertrykker behandlingen av gjeldende inngangslinje, hopp til neste. Den samme rollen somwhile
, men for heleawk
-programmet.awk
har også sitt egetwhile