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' filespielen. - @ terdon: Gutes Golfen. Ich denke, es kann schwierig sein, das zu verstehen.
- @cuonglm Könnten Sie bitte die Rolle von
nexterklären. Ich denke, es unterdrückt der zweite Ausdruck, wenn der erste wahr ist. So etwas wiecontinueinC. - @Alexander Cska:
nextunterdrückt die Verarbeitung der aktuellen Eingabezeile, fahren Sie mit der nächsten fort. Dieselbe Rolle wiewhile, jedoch für das gesamteawk-Programm. Außerdem hatawkeine 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.