Spune că am un fișier:
PRO 1 GLN 5.55112e-17 ILE -6.245e-17 THR 5.55112e-17
Vreau ca fiecare linie care are un număr inegal la 1 în a doua coloană să-l schimbe la 0 și să păstreze restul.
Dacă folosesc if
(adică declarație condițională), totul este OK:
awk "{if($2!=1){print $1,"0"}else{print $0}}" file PRO 1 GLN 0 ILE 0 THR 0
Dar când folosesc blocul condițional, se întâmplă ceva nedorit:
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
Puteți vedea ce nu este corect.
- Cum remediez această eroare?
- De ce apare această eroare?
- Care este diferența dintre o declarație condițională și un bloc condițional?
Răspuns
Într-un if
declarație, aveți o else
. Dacă if
nu se potrivește, ramura else
este executată.
Într-o declarație condiționată, ambele acțiuni sunt executat, indiferent dacă condiția este adevărată sau falsă.
O soluție simplă:
$ awk "$2!=1 {print $1,"0";next};{print $0}" file PRO 1 GLN 0 ILE 0 THR 0
Și o puteți face mai concisă:
$ awk "$2 != 1 {print $1,"0";next};1" file PRO 1 GLN 0 ILE 0 THR 0
Când condiția este adevărată 1
și nu există nicio acțiune, awk
comportamentul implicit este print
. print
fără argument va imprima $0
în mod implicit.
Comentarii
Răspuns
Al doilea bloc din
awk "$2!=1 {print $1,"0"} {print $0}" file
nu este condiționat. Se acționează pentru fiecare linie și astfel imprimă fiecare linie.
În schimb, scrieți:
awk "$2!=1 {print $1,"0"} $2==1 {print $0}" file
Sau scrieți:
awk "$2!=1 {print $1,"0"; next} {print $0}" file
Acest lucru va face ca blocul necondiționat să fie omis, dacă blocul condițional este asociat.
awk '$2!=1?$2=0:"";1' file
.next
. Cred că suprimă a doua tipărire dacă prima este adevărată. Ceva de genulcontinue
înC
.next
suprima procesarea liniei de intrare curente, treceți la următoarea. Același rol cawhile
, dar pentru întregul programawk
. De asemenea,awk
are propriul săuwhile