Podmíněné blokování vs podmíněné prohlášení (pokud)

Řekněme, že mám soubor:

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

Chci, aby každý řádek s číslem nerovným 1 ve druhém sloupci změnil hodnotu na 0 a zbytek ponechal.

Pokud použiji if (tj. podmíněné prohlášení), vše je v pořádku:

awk "{if($2!=1){print $1,"0"}else{print $0}}" file PRO 1 GLN 0 ILE 0 THR 0 

Když ale použiji podmíněný blok, stane se něco nežádoucího:

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 

Vidíte, co se děje.

  • Jak opravím tuto chybu?
  • Proč k této chybě dochází?
  • Čím se liší podmíněný příkaz od podmíněného příkazu?

Odpověď

V if prohlášení, máte else. Pokud if neodpovídá, provede se větev else.

V podmíněném příkazu jsou obě akce provedeno bez ohledu na to, zda je podmínka pravdivá nebo nepravdivá.

Jednoduchá oprava:

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

A můžete to udělat stručnější:

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

Když je podmínka splněna 1 a není tam žádná akce, awk výchozí chování je print. print bez argumentu ve výchozím nastavení vytiskne $0.

Komentáře

  • Můžete jej také golfovat do awk '$2!=1?$2=0:"";1' file.
  • @ terdon: Dobrý golf. Myslím, že to může být těžké OP pochopit.
  • @cuonglm mohl byste mi prosím vysvětlit roli next. Myslím, že to potlačuje druhý výtisk, pokud je první pravdivý. Něco jako continue v C.
  • @Alexander Cska: next potlačuje zpracování aktuálního vstupního řádku, přeskočí na další. Stejná role jako while, ale pro celý awk program. awk má také vlastní while

odpověď

Druhý blok v

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

není podmíněný. Pracuje se s ním pro každý řádek, a proto se vytiskne každý řádek.

Místo toho napište:

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

Nebo napište:

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

To způsobí přeskočení bezpodmínečného bloku, pokud je splněn podmíněný blok.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *