Villkorligt block mot villkorligt uttalande (if)

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

  • Du kan också spela golf i awk '$2!=1?$2=0:"";1' file.
  • @ terdon: Bra golf. Jag tror att det kan vara svårt att OP förstå det.
  • @cuonglm kan du snälla förklara rollen som next. Jag antar att det undertrycker den andra utskriften om den första är sant. Något som continue i C.
  • @ Alexander Cska: next undertrycker bearbetning av den aktuella inmatningsraden, hoppa till nästa. Samma roll som while, men för hela awk -programmet. Dessutom har awk sitt eget while

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.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *