答え1
このBEGIN
ブロックは入力が処理される前に実行されるため、$0
まだ初期化されていません。
ブロックEND
は何もしません。$0
最後の値を保持します。 AWKスクリプトでは、AWKはすべての入力を1行ずつ読み込み、通常のフィールド分割処理(割り当て$0
など)を実行しますが、一致するブロックを見つけることができないため、これは最後に読み取った行だけです。
seq 42 | awk '{ $0 = "21" } END { print }'
END
42ではなく21を出力するので、「ブロックの実行中に最後の行をロードする」ことはありません$0
。
これは文書化されていません。gawk(1)
マンページですが、次の文書に文書化されています。mawk(1)
(明らかにAWK実装の場合):
同様に、ジョブの開始時に、
END
および$0
フィールドの値はNF
最後のレコードで変更されていません。
GNU AWKのマニュアルは次のとおりです。この行動に言及する:
実際、すべてのBWK
awk
、、、mawk
および値はルールで使用するようにgawk
予約されています。$0
END
「BWK」はawk
Brian Kernighanawk
の作品です。「本物awk
」FIXES
;文書に記載されているように、2005年にこの動作を実装しました。
2005年4月24日: posixの要求に応じてENDブロックにet alの値を保持するように
lib.c
修正されました。$0
レポートとコードを提供してくれたhavard eidnesに感謝します。
この変化は以下から見ることができる。「真のawk
」歴史。最新バージョンのBWKはawk
GNU AWKと同じように動作します。
$ echo three fields here | ./awk '{ $0 = "one" } END { print $0 " " NF }'
one 1
$ echo three fields here | ./awk 'END { $0 = "one"; print $0 " " NF }'
one 1
答え2
~によるとGNU awk マニュアル$0
、ENDルールに何を含めるべきかは少し不明です。 POSIXの要件NF
「[それの]価値は維持されるべきです」(*)、しかし言及されていません$0
。
$0
ほとんどの場合、監督のために論理的に維持されなければならないと考えても、標準では維持されるとは言いません。実際、すべてのBWK awk、mawk、およびgawkはルールに使用する$0
値を保持します。END
ただし、他のいくつかの実装とUnix awkの多くの以前のバージョンはそれをサポートしていません。
ある意味では、これらの行動は論理的だと思います。必要に応じて、最後の履歴に簡単にアクセスできるようにブロックを$0
終了します。END
最初のレコードは簡単にアクセスできるため、NR == 1 {...}
特別なキーワードは必要ありません。一方、 BEGIN
最初のレコードをロードする前にブロックを実行すると、最初のレコードに合わせてブロックを設定またはFS
アクティブRS
化できます。
(*その意味が何であるかについてはコメントを参照してください。)