awk表現がありますが、!a[$0]++
正確な評価順序を知りたいです。 awkの文書によると、++
の優先順位はより高いです!
。しかし、この例では、++
サフィックス形式はyes(!++a[$0]
私が理解したところではない)は基本的にawkに「他の部分を最初に評価してから私を評価する」と指示します。この場合、評価順序はどうなりますか?
答え1
ここ(*)が最も高い優先順位を持つことに同意することができるので、簡単にすることa[$0]
ができますx
。
私はあなたが読んだ内容が正しいと言いたいと思います。++
以下よりも優先順位が高くなります!
。
$ awk 'BEGIN{ x=123; tmp = !x++; print tmp, x; }'
0 124
$ awk 'BEGIN{ x=123; tmp = !(x++); print tmp, x; }'
0 124
もちろん。!x++
値を取得しx
て返し、値を増やします。戻り値は123
否定され、生成されます0
。増加した値は後で確認できますx
。
!
しかし、より密接に統合された別の可能性も試してみましょう。
$ awk 'BEGIN{ x=123; tmp = (!x)++; print tmp, x; }'
awk: cmd. line:1: BEGIN{ x=123; tmp = (!x)++; print tmp, x; }
awk: cmd. line:1: ^ syntax error
まあ、そうです。今、この!
値は最初に値を取得してx
からそれを反転して返すため、機能しません0
。もう少し増やさなければなりません++
。結果を再保存。しかし、0
変数ではない値にすぎず、保存することはできません。したがって、エラーが発生しました。 (似ていると(1+2)++
同じエラーが発生します。)
したがって、++
優先順位が高いほど、返される値には明確ではない隠された副作用があります。
(*購読事業者は表示されません。優先順位テーブル標準ではC演算子優先順位テーブルただし、優先順位が低い場合、式は実際には機能しません。 )
答え2
デモ:
$ cat file
1 a
2 b
1 c
2 d
3 e
$ awk '!a[$1]++' file
1 a
2 b
3 e
++
まず発生します。事後増分なので、最初の行の場合はa[$1]++
a [1]の値を増やしますが、0を返し、否定はそれをtrueに置き換えてから最初の行を印刷します。 2号線と同じです。 3行目の場合、a [1]にはすでに値1があり、ポストインクリメントは値を2に設定して1を返すため、falseは無効になります。
mawkのマニュアルページがより明確になりました。
New expressions are composed with the following operators in order of increasing
precedence.
assignment = += -= *= /= %= ^=
conditional ? :
logical or ||
logical and &&
array membership in
matching ~ !~
relational < > <= >= == !=
concatenation (no explicit operator)
add ops + -
mul ops * / %
unary + -
logical not !
exponentiation ^
inc and dec ++ -- (both post and pre)
field $