awk variable assignment-- inside braces or not?

So, in awk, I've always put my variable assignments inside of the curly braces, just like dad, and grandpa, and the 26 generations before them. But today I came upon an awk statement that had them outside the braces-- blasphemy!

Seriously, though, is there any practical difference? I was surprised to see that the following trivial commands worked identically:

ls | awk 'x = $0 {print x}'
ls | awk '{x = $0 ; print x}'

I'm showing my ignorance here, but if I'd been asked whether those would work, I would have predicted that the first would fail and the second would work; but, they both work.

I'm simply wondering if there's a difference that this example doesn't bring to light-- some slightly more subtle gotcha, perhaps? Or are they functionally and logically identical?

They are not identical.

$printf '%s\n' 0 1 '' 'not empty' | awk '{x = $0; print x}
0
1

not empty
$printf '%s\n' 0 1 '' 'not empty' | awk 'x = $0 {print x}
1
not empty

In AWK, the value of an assignment statement is the value assigned. The later version is using the value of $0 to determine if the action will be executed. In the former, the action is always performed.

Regards,
Alister

1 Like

There is a difference:

% touch 0 1 2 3

% ls | awk 'x = $0 {print x}'
1
2
3

% ls | awk '{x = $0 ; print x}'
0
1
2
3

Assignment is an expression in awk. These two commands are the same only when $0 is true - not 0 or "". In this case x=$0 gives the true value and the action part is executed.

1 Like

Ah, thank you, both. I'd never considered that. So, when outside, the operation is simultaneously making an assignment and establishing a true/false condition. Slight variations of the example given...

seq -2 2 | awk 'x = $0 {print x}'

   and...

( seq -3 -1 ; echo "" ; seq 0 3 ) | awk 'x = $0 {print x}'

Again, thanks. It's a new little bit I'd never encountered before.