2

It is my understanding that in awk a conditional evaluation could be started using either of the following:

if ($0 ~ /no/) {cmd}
($0 ~ /no/) {cmd}
$0 ~ /no/ {cmd}
/no/ {cmd}

In the generic command line

BEGIN {  }  (body) END {  }

I find it most logical to enclose (body) in brackets, as in {(body} (referred to as "bracketed"). 

Under GNU awk, Ubuntu 12.04, only the 1st of the 4 options executes if bracketed - at least on my machine (the others produce syntax errors). If i run the line un-bracketed, only the 1st failed, the rest 3 work fine. Could someone carefully explain why that is so?

Kent
  • 189,393
  • 32
  • 233
  • 301
gnometorule
  • 2,151
  • 2
  • 20
  • 29
  • Welcome to Stack Overflow. Please improve your question by posting some [properly formatted](http://stackoverflow.com/editing-help) output from your code and all **relevant** error messages exactly as they appear. Also, make sure to include some samples of what you're testing against. – Todd A. Jacobs Sep 22 '13 at 16:16
  • Formatting has been corrected; as to examples: the question is clear as is: the "example" would be to rum it as usual (awk ' ' , receiving the nor very helpful "syntax error in line 1 near { syntax error in line 1 near }". – gnometorule Sep 22 '13 at 16:21
  • One clarification: I run it as 'awk', which I believe to be (from the man page) nawk, not awk proper. – gnometorule Sep 22 '13 at 16:28
  • do you mean `awk 'if ($0 ~ /no/) {cmd}' input` worked by you? it shouldn't though. – Kent Sep 22 '13 at 16:33
  • @Kent: You are right; it doesn't. I meant to edit question text reflecting this, but was not allowed to. Thanks much. – gnometorule Sep 22 '13 at 16:40
  • @gnometorule I edited the question for you, I hope it is ok. – Kent Sep 22 '13 at 16:45

2 Answers2

3

Syntactically, an awk script is a set of rules, like the following [Ref]:

pattern { action }
pattern { action }
.... 

Where pattern is an expression, and action is a series of commands that are executed if pattern is evaluated to true (a non-zero number, or a non-empty string).

If the pattern is omitted, then action will be executed for every record.

If the { action } part is omitted, the default action is executed, which is { print $0 } or { print } (equivalent).

As you mentioned in the question, pattern can be BEGIN, END, ... etc, or any other expression.

Your first example will be executed correctly in the { action } block, since it is a command. The other three options are not commands, but are combinations of pattern { action } blocks.

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
user000001
  • 32,226
  • 12
  • 81
  • 108
  • 1
    +1 A non-empty string is also a true value http://www.gnu.org/software/gawk/manual/html_node/Truth-Values.html#Truth-Values – glenn jackman Sep 22 '13 at 20:32
3

awk statements follow the rule:

PATTERN{action}

So BEGIN or END are just special PATTERNs. basically if PATTERN is true, do the action in {..}

PATTERN could be regex, expression and range also empty.

the empty pattern looks like:

awk '{print "foo"}' input

You can read http://www.gnu.org/software/gawk/manual/gawk.html section 7.1 for deatails.

Back to your question, if you executed those 4 lines in Action part, that is, between {...}, (in fact empty pattern), only the first, with if is valid conditional statement. However if you use the matching check as pattern, (outside the {..}):

if ($0 ~ /no/) {cmd} # this would ***NOT*** work, because it is statment, not valid awk expression. (I don't know how did you make it work.)

($0 ~ /no/) {cmd} # this will work, it is a boolean expression

$0 ~ /no/ {cmd} # same as above

/no/ {cmd} # this is regexp pattern, so it works too. 
Kent
  • 189,393
  • 32
  • 233
  • 301