Blok warunkowy a instrukcja warunkowa (jeśli)

18

Powiedz, że mam plik:

PRO 1
GLN 5.55112e-17
ILE -6.245e-17
THR 5.55112e-17

Chcę, aby każdy wiersz, który ma liczbę nierówną do 1 w drugiej kolumnie, zmienił go na 0 i zatrzymał resztę.

Jeśli używam if(tj. Instrukcji warunkowej), wszystko jest w porządku:

awk '{if($2!=1){print $1,"0"}else{print $0}}' file
PRO 1
GLN 0
ILE 0
THR 0

Ale kiedy używam bloku warunkowego, dzieje się coś niepożądanego:

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

Możesz zobaczyć, co jest nie tak.

  • Jak naprawić ten błąd?
  • Dlaczego występuje ten błąd?
  • Czym różni się instrukcja warunkowa od bloku warunkowego?
Ooker
źródło

Odpowiedzi:

26

W ifoświadczeniu masz else. Jeśli ifnie pasuje, elsegałąź jest wykonywana.

W instrukcji warunkowej oba działania są wykonywane, niezależnie od tego, czy warunek jest prawdziwy czy fałszywy.

Prosta poprawka:

$ awk '$2!=1 {print $1,"0";next};{print $0}' file
PRO 1
GLN 0
ILE 0
THR 0

I możesz uczynić to bardziej zwięzłym:

$ awk '$2 != 1 {print $1,"0";next};1' file
PRO 1
GLN 0
ILE 0
THR 0

Gdy warunek jest spełniony 1i nie ma akcji, awkzachowaniem domyślnym jest print. printbez argumentu zostanie wydrukowany $0domyślnie.

Cuonglm
źródło
4
Możesz także zagrać w golfa awk '$2!=1?$2=0:"";1' file.
terdon
@terdon: Dobry golf. Myślę, że OP może być trudne do zrozumienia.
cuonglm,
1
@cuonglm mógłbyś wyjaśnić rolę next. Sądzę, że pomija drugi wydruk, jeśli pierwszy jest prawdziwy. Coś jak continuew C.
Alexander Cska
@Alexander Cska: nextwstrzymuje przetwarzanie bieżącej linii wejściowej, przejdź do następnej. Ta sama rola while, ale dla całego awkprogramu. Ponadto awkma swój własnywhile
cuonglm
10

Drugi blok w

awk '$2!=1 {print $1,"0"} {print $0}' file

nie jest warunkowy. Działa na każdą linię, a zatem drukuje każdą linię.

Zamiast tego napisz:

awk '$2!=1 {print $1,"0"} $2==1 {print $0}' file

Lub napisz:

awk '$2!=1 {print $1,"0"; next} {print $0}' file

Spowoduje to pominięcie bloku bezwarunkowego, jeśli zostanie dopasowany blok warunkowy.

Kyle Jones
źródło