Säg att jag har en fil:
PRO 1 GLN 5.55112e-17 ILE -6.245e-17 THR 5.55112e-17
Jag vill att varje rad som har ett tal som är lika med 1 i den andra kolumnen ska ändra det till 0 och behålla resten.
Om jag använder if (dvs. villkorligt uttalande), allt är OK:
awk "{if($2!=1){print $1,"0"}else{print $0}}" file PRO 1 GLN 0 ILE 0 THR 0
Men när jag använder det villkorliga blocket händer något oönskat:
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 vad som är fel.
- Hur fixar jag det här felet?
- Varför uppstår detta fel?
- Vad skiljer sig mellan ett villkorligt uttalande och ett villkorligt block?
Svar
I en if uttalande, du har ett else. Om if inte överensstämmer, körs grenen else.
I ett villkorligt uttalande är båda åtgärderna körs, oavsett om villkoret är sant eller falskt.
En enkel fix:
$ awk "$2!=1 {print $1,"0";next};{print $0}" file PRO 1 GLN 0 ILE 0 THR 0
Och du kan göra det mer kortfattat:
$ awk "$2 != 1 {print $1,"0";next};1" file PRO 1 GLN 0 ILE 0 THR 0
När villkoret är sant 1 och det finns ingen åtgärd, awk standardbeteende är print. print utan argument skrivs ut $0 som standard.
Kommentarer
Svar
Det andra blocket i
awk "$2!=1 {print $1,"0"} {print $0}" file
är inte villkorligt. Det handlas för varje rad och skrivs alltså ut varje rad.
Skriv istället:
awk "$2!=1 {print $1,"0"} $2==1 {print $0}" file
Eller skriv:
awk "$2!=1 {print $1,"0"; next} {print $0}" file
Detta hoppar över det ovillkorliga blocket om det villkorliga blocket matchas.
awk '$2!=1?$2=0:"";1' file.next. Jag antar att det undertrycker den andra utskriften om den första är sant. Något somcontinueiC.nextundertrycker bearbetning av den aktuella inmatningsraden, hoppa till nästa. Samma roll somwhile, men för helaawk-programmet. Dessutom harawksitt egetwhile