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' filegolfen.nextuitleggen. Ik denk dat het onderdrukt de tweede afdruk als de eerste waar is. Iets alscontinueinC.nextonderdrukt de verwerking van de huidige invoerregel, ga naar de volgende. Dezelfde rol alswhile, maar voor het heleawkprogramma. Bovendien heeftawkzijn eigenwhile