Betinget blokering vs betinget erklæring (hvis)

Sig, at jeg har en fil:

PRO 1 GLN 5.55112e-17 ILE -6.245e-17 THR 5.55112e-17 

Jeg vil have, at hver linje, der har et tal, der ikke er lig med 1 i anden kolonne, skal ændre det til 0 og beholde resten.

Hvis jeg bruger if (dvs. betinget erklæring), 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 bruger den betingede blok, sker der noget 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, hvad der er forkert.

  • Hvordan løser jeg denne fejl?
  • Hvorfor opstår denne fejl?
  • Hvad er forskellen mellem en betinget erklæring og en betinget blok?

Svar

I en if udsagn, du har en else. Hvis if ikke stemmer overens, udføres else -grenen.

I en betinget erklæring er begge handlinger udført, uanset om betingelsen er sand eller falsk.

En simpel løsning:

$ awk "$2!=1 {print $1,"0";next};{print $0}" file PRO 1 GLN 0 ILE 0 THR 0 

Og du kan gøre det mere kortfattet:

$ awk "$2 != 1 {print $1,"0";next};1" file PRO 1 GLN 0 ILE 0 THR 0 

Når betingelsen er sand 1 og der ikke er nogen handling, awk standardadfærd er print. print uden argument udskrives $0 som standard.

Kommentarer

  • Du kan også spille golf i awk '$2!=1?$2=0:"";1' file.
  • @ terdon: God golf. Jeg tror det kan være svært at OP forstå det.
  • @cuonglm kan du venligst forklare rollen som next. Jeg antager, at det undertrykker det andet tryk, hvis det første er sandt. Noget som continue i C.
  • @ Alexander Cska: next undertrykker behandlingen af den aktuelle inputlinje, spring til den næste. Den samme rolle som while, men for hele awk -programmet. awk har også sit eget while

Svar

Den anden blok i

awk "$2!=1 {print $1,"0"} {print $0}" file 

er ikke betinget. Den handles for hver linje og udskriver således 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 springer over den ubetingede blok, hvis den betingede blok matches.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *