пост-уменьшение NF в awk

#awk

#awk

Вопрос:

Я немного смущен следующим:

 $ 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
 

Я вижу такое же поведение в awk version 20070501 (macos) и GNU Awk 4.0.2 . Почему пост-уменьшение NF в 3-м случае не применяется? Является ли такое поведение ожидаемым, предписанным стандартом или особенностью реализации?


РЕДАКТИРОВАТЬ Эд Мортон: FWIW Я бы нашел следующий более убедительный пример:

 $ 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
 

вопрос в том, почему последний пример (пост-уменьшение с присвоением) ведет себя иначе, чем во всех других случаях, независимо от того, какой из них, по вашему мнению, должен быть эквивалентен.

Комментарии:

1. например echo 'foo bar baz' | awk '{printf "%d:", NF; $(--NF)=""; print NF}' , будет выводить 3:2

Ответ №1:

Значение пост-уменьшения — это значение переменной до ее уменьшения. Из-за этого в последнем случае добавляется новое поле после его уменьшения NF , которое обновляется NF .

 $(NF--) = "";
 

эквивалентно

 temp = NF;  # temp == 3
NF--;       # NF == 2
$temp = ""; # adds a new field 3, so now NF == 3
 

Комментарии:

1. Верно, но, учитывая, что это работает в этой реализации, это то, что он делает.

2. Да, похоже, это то, что происходит правильно. Конечно, мы могли бы протестировать это, используя пост-инкремент для аналогичной функциональности — это поведение задается POSIX, поэтому оно удаляет «неопределенное поведение» из уравнения. @AndyLester Я удалил этот комментарий, поскольку не думаю, что он действительно имеет отношение к этому, в конце концов, я слишком быстро отклонил его как «просто не делай этого» (хотя я все еще думаю, что это лучший совет!).