AWKで入力全体を集計する

行単位の処理を見てきましたが、たとえば「これらの文庫を全部買ったら、い くらになるのだろう?」という疑問には、各行にある価格の総和を求めなけれ ばなりませんから行単位の処理だけではすみません。そこで、BEGINとEND というパターンが必要になります。

    % gawk 'BEGIN {処理1} {行単位の処理} END {処理2}' miyabe.new

の形式でプログラムを与えると、 AWKは、1行目を処理する前にまず 処理1を行い、その後で行単位の処理を入力が終るまで繰 り返し、最終行に対する行単位の処理の終ってから最後に処理2を行います。BEGINやENDは一方または両方を省略しても構いませ ん。

    % gawk '{行単位の処理} END {処理2}' miyabe.new
    % gawk 'BEGIN {処理1} {行単位の処理}' miyabe.new
    % gawk '{行単位の処理}' miyabe.new

また「行単位の処理」を/正規表現/やNRを使って特定の行だけに行わせても構 いません。

    % gawk '/96\// {行単位の処理} END {処理2}' miyabe.new
    % gawk 'BEGIN {処理1} /96\// {行単位の処理}' miyabe.new
    % gawk '/96\// {行単位の処理}' miyabe.new

実例を上げましょう。miyabe.newについて「これらの文庫を全部 買ったら、いくらになるのだろう?」という疑問には、変数allに 価格の合計を保存することにして、次のようにします。変数名はアルファベッ トの並びならなんでも構いません。

    % gawk 'BEGIN {all=0;} { all += $2; } END { print all;}' miyabe.new
    25798
    %

まずBEGINで変数allを0に初期化しています。その後、各行の処 理でallに$2の内容(一冊づつの値段)を加算しています。 += という演 算子は Cでお馴染の加算用の演算子ですね。そして全ての行の処理が終った とき、全ての価格を加算したものがallに入っていますので、ENDの処理で総 和allを表示しているのです。消費税を考慮に入れたいなら1.05を掛けておけ ばいいですね。

    % gawk 'BEGIN {all=0;} { all += $2; } END { print all*1.05;}' miyabe.new
    27087.9
    %

96年の出版分だけなら/正規表現/を使って和を取る部分を制限しましょう。

    % gawk 'BEGIN {all=0;} /96\// { all += $2; } END { print all*1.05;}' miyabe.new
    5809.65
    %

ここでは説明のためにBEGINを使って変数を0に初期化しましたが、実は AWKでは初めて使われる変数は0に自動的に初期化されますので、ここで出 てきたプログラムは全部BEGIN {all=0;}を省略できます。

    % gawk '/96\// { all += $2; } END { print all*1.05;}' miyabe.new
    5809.65
    %

OGURISU Osamu
2004-01-15