Conditional block vs conditional statement (if)

Say I have a file:

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

I want every line that has a number unequal to 1 in the second column to change it to 0 and keep the rest.

If I use if (i.e conditional statement), everything is OK:

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

But when I use the conditional block, something undesired happens:

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

You can see what’s wrong.

  • How do I fix this error?
  • Why does this error occur?
  • What’s the different between a conditional statement and a
    conditional block?
Asked By: Ooker

||

The second block in

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

isn’t conditional. It is acted upon for every line, and thus prints every line.

Instead, write:

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

Or write:

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

This will cause the unconditional block to be skipped, if the conditional block is matched.

Answered By: Kyle Jones

In an if statement, you have an else. If if doesn’t match, the else branch is executed.

In a conditional statement, both actions are executed, regardless of the condition is true or false.

A simple fix:

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

And you can make it more concise:

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

When condition is true 1 and there is no action, awk default behavior is print. print with no argument will print $0 by default.

Answered By: cuonglm
Categories: Answers Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.