このワンライナーは、事前に並べ替えることなく、テキスト入力から重複する行を削除します。
例:
$ cat >f
q
w
e
w
r
$ awk '!a[$0]++' <f
q
w
e
r
$
私がインターネットで見つけた元のコードは次のとおりです。
awk'!_ [$ 0] ++'
_
を使用したので、これはさらに複雑でした。 Perlのように、awkで特別な意味を持ちますが、それは単なる配列の名前であることが判明しました。
これで、ワンライナーの背後にあるロジックを理解しました。
各入力行はハッシュ配列のキーとして使用されるため、完了すると、ハッシュには到着順に一意の行が含まれます。
私が学びたいのは、この表記法がawkによってどのように正確に解釈されるかということです。例えば。なんという強打のサイン(!
)は、このコードスニペットの他の要素を意味します。
どのように機能しますか?
承認された回答:
これが「直感的な」答えです。awkのメカニズムの詳細については、@Cuonglmの
を参照してください。
この場合、!a [$ 0] ++
、ポストインクリメント ++
少しの間取っておくこともできますが、式の値は変更されません。したがって、!a [$ 0]
のみを見てください。 。ここ:
a[$0]
現在の行を使用します$0
配列のキーとしてa
、そこに保存されている値を取得します。この特定のキーが以前に参照されたことがない場合は、 a [$ 0]
空の文字列に評価されます。
!a[$0]
!コード> 以前の値を否定します。空またはゼロ(false)の場合、真の結果が得られます。ゼロ以外(true)の場合、falseの結果になります。式全体がtrueと評価された場合、つまり
a [$ 0]
最初に設定されていなかった場合、行全体がデフォルトのアクションとして出力されます。
また、古い値に関係なく、ポストインクリメント演算子は a [$ 0]
に1を追加します 、したがって、次に配列内の同じ値にアクセスすると、正の値になり、条件全体が失敗します。