以前の記事で書いた、以下のようなgetlineを使うバッドパターンを考えます。
三行目にマッチし、その二行あとを捕獲して表示する例です。
$ seq 1 10 | gawk '/3/{getline; getline; print}'
これは、getlineを使わない形で以下のように書き換わります。
$ seq 1 10 | gawk 'z&&!--z;/3/{z=2}'
正規表現処理に入る前に、奇妙な構文を処理することになります。
zは変数なので、任意の文字列でも成立します。
試しに、この奇妙な構文を削除し/3/が成立した状態のzを確認すると
$ seq 1 10 | gawk 'z;/3/{print z}'
そう、空で何も表示されません。
この事から、
- /3/が成立した行(=3行目)から、変数zが内容2で実体をもつ
- 4行目の処理が入る前に、Z(=2)の評価が入る
- 評価前にzが1減算され、否定論理で評価される。この時点で、z=1
- 5行目に入ると、z=1で引き続き変数zは存在する
- 評価前にzが1減算され、否定論理で評価される。この時点で、z=0。
- この時点で変数zが実体を持ち、かつこれ以上のzの減算が不可能という条件が成立する。
- 上記条件が成立した行の情報が保持される。
- 全行を評価後、保存された行情報が出力される
といった流れをとると推測されます。
気をつけて読めば、何とか理解できる処理です。
awkにおける変数の処理方法が分かってないと、意味不明な構文ではあるのですが……。