条件付きブロックと条件付きステートメント(if)


17

ファイルがあるとします:

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

2番目の列の番号が1でないすべての行を0に変更し、残りを保持するようにします。

私が使用する場合if(つまり、条件付きステートメント)、すべてがOKです:

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

しかし、条件ブロックを使用すると、望ましくないことが起こります。

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

何がおかしいのかわかります。

  • このエラーを修正するにはどうすればよいですか?
  • なぜこのエラーが発生するのですか?
  • 条件付きステートメントと条件付きブロックの違いは何ですか?

回答:


26

if声明、あなたが持っていますelseif一致しない場合、elseブランチが実行されます。

条件付きステートメントでは、条件がtrueまたはfalseであるかに関係なく、両方のアクションが実行されます。

簡単な修正:

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

そして、あなたはそれをより簡潔にすることができます:

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

条件がtrue 1でアクションがない場合、awkデフォルトの動作はprintです。print引数なしでは$0、デフォルトで印刷されます。


4
ゴルフすることもできawk '$2!=1?$2=0:"";1' fileます。
テルドン

@terdon:良いゴルフ。OPがそれを理解することは難しいと思います。
cuonglm 14

1
@cuonglmの役割を説明してくださいnext。最初の印刷がtrueの場合、2番目の印刷を抑制します。以下のようなものcontinueの中でC
アレクサンダーCska

@Alexander Cska:next現在の入力行の処理を抑制し、次の入力行にスキップします。と同じ役割ですがwhileawkプログラム全体に対して。また、awk独自のwhile
-cuonglm

10

の2番目のブロック

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

条件付きではありません。それはすべての行に対して実行され、したがってすべての行を印刷します。

代わりに、次のように書きます:

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

または書く:

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

これにより、条件ブロックが一致した場合、無条件ブロックがスキップされます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.