Меня немного смущает следующее:

$ 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. Почему не применяется постдекремент НФ в 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

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

awk
4
William Pursell 11 Фев 2021 в 20:30

1 ответ

Лучший ответ

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

$(NF--) = "";

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

temp = NF;  # temp == 3
NF--;       # NF == 2
$temp = ""; # adds a new field 3, so now NF == 3
7
Ed Morton 11 Фев 2021 в 18:21