Ř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
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.
awk '$2!=1?$2=0:"";1' file
.next
. Myslím, že to potlačuje druhý výtisk, pokud je první pravdivý. Něco jakocontinue
vC
.next
potlačuje zpracování aktuálního vstupního řádku, přeskočí na další. Stejná role jakowhile
, ale pro celýawk
program.awk
má také vlastníwhile