Bye Bye Moore

猫マンション建築の野望を胸に零細事業主として資本主義の荒波に漕ぎ出したアラサー男の技術メモ

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