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 (dh bedingte Anweisung), alles ist in Ordnung:
awk "{if($2!=1){print $1,"0"}else{print $0}}" file PRO 1 GLN 0 ILE 0 THR 0
Wenn ich jedoch den bedingten Block verwende, 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 falsch ist.
- Wie behebe ich diesen Fehler?
- Warum tritt dieser Fehler auf?
- Was ist der Unterschied zwischen einer bedingten Anweisung und einem bedingten Block?
Antwort
In einem if
Anweisung, Sie haben eine else
. Wenn if
nicht übereinstimmt, wird der Zweig else
ausgeführt.
In einer bedingten Anweisung sind 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äziser 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 keine Aktion ausgeführt wird, awk
ist print
. print
ohne Argument gibt standardmäßig $0
aus.
Kommentare
- Sie können es auch in
awk '$2!=1?$2=0:"";1' file
spielen. - @ terdon: Gutes Golfen. Ich denke, es kann schwierig sein, das zu verstehen.
- @cuonglm Könnten Sie bitte die Rolle von
next
erklären. Ich denke, es unterdrückt der zweite Ausdruck, wenn der erste wahr ist. So etwas wiecontinue
inC
. - @Alexander Cska:
next
unterdrückt die Verarbeitung der aktuellen Eingabezeile, fahren Sie mit der nächsten fort. Dieselbe Rolle wiewhile
, jedoch für das gesamteawk
-Programm. Außerdem hatawk
eine eigenewhile
Antwort
Der zweite Block in
awk "$2!=1 {print $1,"0"} {print $0}" file
ist nicht bedingt. Er wird für jede Zeile bearbeitet und druckt somit jeden Zeile.
Schreiben Sie stattdessen:
awk "$2!=1 {print $1,"0"} $2==1 {print $0}" file
Oder schreiben Sie:
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.