BEGIN 部で処理した結果をアクションで使う

基本的に awk は「grep + 処理」を具現化したものだそうで、The A-Z of Programming Languages: AWK には Aho 博士が "We were heavily influenced by GREP," (GREP に大きく影響を受けましたよ) と答えていることでも分かります。 そのため、アクションで処理するには、通常、何らかのインプットを入れてあげなければいけません。

そんな中、「2 ちゃんねる」の「ム板」で面白い記事がありましたので、勝手ながら紹介します。 自分でもやったことはあったのですが、すっかり忘れていましたが、BEGIN で ARGV, ARGC をセットしてやるとアクションに渡されるというものです。 具体的には 1 つのファイルであれば ARGV1 をセットして、ARGC を 2 にセットします。

#! /usr/bin/gawk -f
# self_extract.awk

BEGIN {
    # テンポラリファイルの設定
    tmp_file = "test.tmp";

    # 1 から 20 までの数をテンポラリファイルに保存
    for (i = 1; i <= 20; i++) {
        print i > tmp_file;
    }
    close(tmp_file);

    # ARGV, ARGC をセット
    ARGV[1] = tmp_file;
    ARGC = 2;
}

# BEGIN 部で書き込んだファイルを読み込んで処理
$0 % 3  == 0 {
    print $0 ^ 2;
}

ここで注意しなければならないのは、BEGIN 部で書き込んだファイルは一度 close() でクローズする必要があるところです。 実際に実行してみましょう。

$ gawk -f self_extract.awk
9
36
81
144
225
324

実用的な使い道は思いつきませんが、自分の作ったスクリプトのテストケースを BEGIN 部で作成しておいて、テストを行う場合にのみテスト用の入力ファイルを自己生成するような場合に使えるかもしれません。

上記の場合には、Unix 系 OS の場合であれば seq コマンドの出力をパイプで渡す方が楽ですが、awk 単独で行える方法も知っておくと便利かもしれません。

tag_nawk.pngtag_nawk.pngtag_nawk.pngtag_nawk.png