#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 Я удалил этот комментарий, поскольку не думаю, что он действительно имеет отношение к этому, в конце концов, я слишком быстро отклонил его как «просто не делай этого» (хотя я все еще думаю, что это лучший совет!).