Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

post-decrement of NF in awk

Tags:

awk

I'm a bit confused by the following:

$ echo foo bar baz | awk '{printf "%d:", NF--; print NF}'
3:2
$ echo foo bar baz | awk '{printf "%d:", NF; $NF=""; NF -= 1; print NF}' 
3:2
$ echo foo bar baz | awk '{printf "%d:", NF; $(NF--)=""; print NF}' 
3:3

I see the same behavior in awk version 20070501 (macos) and GNU Awk 4.0.2. Why does the post-decrement of NF in the 3rd case not apply? Is that behavior expected, mandated by a standard, or a quirk of the implementation?


EDIT by Ed Morton: FWIW I'd find the following a more compelling example:

$ echo foo bar baz | awk '{printf "%d:", NF; NF--; $NF=""; print NF}'
3:2

$ echo foo bar baz | awk '{printf "%d:", NF; --NF; $NF=""; print NF}'
3:2

$ echo foo bar baz | awk '{printf "%d:", NF; $NF=""; NF--; print NF}'
3:2

$ echo foo bar baz | awk '{printf "%d:", NF; $NF=""; --NF; print NF}'
3:2

$ echo foo bar baz | awk '{printf "%d:", NF; $(--NF)=""; print NF}'
3:2

$ echo foo bar baz | awk '{printf "%d:", NF; $(NF--)=""; print NF}'
3:3

with the question being why does the last example (post-decrement with assignment) behave differently from all of the other cases, regardless of which one you think it should be equivalent to.

like image 569
William Pursell Avatar asked Mar 02 '23 17:03

William Pursell


1 Answers

The value of a post-decrement is the value of the variable before it's decremented. Because of this, the last case is adding a new field after it decrements NF, which updates NF.

$(NF--) = "";

is equivalent to

temp = NF;  # temp == 3
NF--;       # NF == 2
$temp = ""; # adds a new field 3, so now NF == 3
like image 121
Barmar Avatar answered Mar 04 '23 08:03

Barmar