Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

awkにおけるgetlineのバッドノウハウを消し去る構文「c&&!--c;」についてちゃんと理解する

以前の記事で書いた、以下のような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}'

そう、空で何も表示されません。

この事から、

  1. /3/が成立した行(=3行目)から、変数zが内容2で実体をもつ
  2. 4行目の処理が入る前に、Z(=2)の評価が入る
  3. 評価前にzが1減算され、否定論理で評価される。この時点で、z=1
  4. 5行目に入ると、z=1で引き続き変数zは存在する
  5. 評価前にzが1減算され、否定論理で評価される。この時点で、z=0。
  6. この時点で変数zが実体を持ち、かつこれ以上のzの減算が不可能という条件が成立する。
  7. 上記条件が成立した行の情報が保持される。
  8. 全行を評価後、保存された行情報が出力される

といった流れをとると推測されます。
気をつけて読めば、何とか理解できる処理です。
awkにおける変数の処理方法が分かってないと、意味不明な構文ではあるのですが……。

参考もと

awk.info