it-swarm.com.de

Bedingter Block gegen bedingte Anweisung (if)

Angenommen, ich habe eine Datei:

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

Ich möchte, dass jede Zeile mit einer Zahl ungleich 1 in der zweiten Spalte diese in 0 ändert und den Rest behält.

Wenn ich if verwende (d. H. Bedingte Anweisung), ist alles in Ordnung:

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

Aber wenn ich den bedingten Block benutze, passiert etwas Unerwünschtes:

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

Sie können sehen, was los ist.

  • Wie behebe ich diesen Fehler?
  • Warum tritt dieser Fehler auf?
  • Was ist der Unterschied zwischen einer bedingten Anweisung und einem bedingten Block?
18
Ooker

In einer if -Anweisung haben Sie ein else. Wenn if nicht übereinstimmt, wird der Zweig else ausgeführt.

In einer bedingten Anweisung werden beide Aktionen ausgeführt, unabhängig davon, ob die Bedingung wahr oder falsch ist.

Eine einfache Lösung:

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

Und Sie können es prägnanter gestalten:

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

Wenn die Bedingung erfüllt ist 1 und es gibt keine Aktion, awk Standardverhalten ist print. print ohne Argument wird $0 standardmäßig.

26
cuonglm

Der zweite Block in

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

ist nicht bedingt. Es wird für jede Zeile bearbeitet und druckt somit jede Zeile.

Schreiben Sie stattdessen:

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

Oder schreiben:

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

Dies führt dazu, dass der unbedingte Block übersprungen wird, wenn der bedingte Block übereinstimmt.

10
Kyle Jones