Bloc condițional vs declarație condițională (dacă)

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

  • Puteți, de asemenea, să îl jucați în awk '$2!=1?$2=0:"";1' file.
  • @ terdon: Bun golf. Cred că PO poate fi dificil să înțeleagă acest lucru.
  • @cuonglm ai putea explica rolul next. Cred că suprimă a doua tipărire dacă prima este adevărată. Ceva de genul continue în C.
  • @Alexander Cska: next suprima procesarea liniei de intrare curente, treceți la următoarea. Același rol ca while, dar pentru întregul program awk. De asemenea, awk are propriul său while

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.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *