Stel dat ik een bestand heb:
PRO 1 GLN 5.55112e-17 ILE -6.245e-17 THR 5.55112e-17
Ik wil dat elke regel met een getal ongelijk aan 1 in de tweede kolom het verandert in 0 en de rest behoudt.
Als ik if
gebruik (dwz conditionele verklaring), alles is in orde:
awk "{if($2!=1){print $1,"0"}else{print $0}}" file PRO 1 GLN 0 ILE 0 THR 0
Maar als ik het voorwaardelijke blok gebruik, gebeurt er iets ongewenst:
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
U kunt zien wat er mis is.
- Hoe los ik deze fout op?
- Waarom treedt deze fout op?
- Wat is het verschil tussen een voorwaardelijke verklaring en een voorwaardelijke blokkering?
Antwoord
In een if
instructie, je hebt een else
. Als if
niet “overeenkomt, wordt de else
branch uitgevoerd.
In een conditionele instructie worden beide acties uitgevoerd. uitgevoerd, ongeacht of de voorwaarde waar of onwaar is.
Een eenvoudige oplossing:
$ awk "$2!=1 {print $1,"0";next};{print $0}" file PRO 1 GLN 0 ILE 0 THR 0
En je kunt het beknopter maken:
$ awk "$2 != 1 {print $1,"0";next};1" file PRO 1 GLN 0 ILE 0 THR 0
Als de voorwaarde waar is 1
en er is geen actie, awk
standaardgedrag is print
. print
zonder argument zal standaard $0
afdrukken.
Reacties
Antwoord
Het tweede blok in
awk "$2!=1 {print $1,"0"} {print $0}" file
is niet voorwaardelijk. Er wordt voor elke regel op gereageerd, en dus wordt elke regel afgedrukt regel.
Schrijf in plaats daarvan:
awk "$2!=1 {print $1,"0"} $2==1 {print $0}" file
Of schrijf:
awk "$2!=1 {print $1,"0"; next} {print $0}" file
Hierdoor zal het onvoorwaardelijke blok worden overgeslagen als het voorwaardelijke blok overeenkomt.
awk '$2!=1?$2=0:"";1' file
golfen.next
uitleggen. Ik denk dat het onderdrukt de tweede afdruk als de eerste waar is. Iets alscontinue
inC
.next
onderdrukt de verwerking van de huidige invoerregel, ga naar de volgende. Dezelfde rol alswhile
, maar voor het heleawk
programma. Bovendien heeftawk
zijn eigenwhile