Voorwaardelijk blok versus voorwaardelijke verklaring (if)

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

  • Je kunt het ook naar awk '$2!=1?$2=0:"";1' file golfen.
  • @ terdon: Goed golfen. Ik denk dat het moeilijk kan zijn om OP te begrijpen om dat te begrijpen.
  • @cuonglm kun je de rol van next uitleggen. Ik denk dat het onderdrukt de tweede afdruk als de eerste waar is. Iets als continue in C.
  • @Alexander Cska: next onderdrukt de verwerking van de huidige invoerregel, ga naar de volgende. Dezelfde rol als while, maar voor het hele awk programma. Bovendien heeft awk zijn eigen while

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.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *