`!a[$0]++` の awk 演算子優先順位

`!a[$0]++` の awk 演算子優先順位

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               $

関連情報