Shoeisha Technology Media

CodeZine(コードジン)

記事種別から探す

GNU AWKはまだまだ成長中! ユーザーの声をもとに作成された拡張機能を組み込んでみよう

► 「シェル芸」に効く GNU AWK処方箋 最終回 (月刊『シェルスクリプトマガジン January 2015(vol.21)』より転載)

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2015/01/26 14:00

 GNU AWK(以下、gawk)は標準でGNU MPFR(Multiple Precision Floating-Point Reliably)を用いた拡張があり、数値演算能力が大幅に改善されました。また、個別に拡張機能をロードすることも可能になっており、共有オブジェクトをロードすることにより従来のAWKではできなかった機能を拡張することができます。最終回の今回はこれらのGNU AWKならではの拡張機能について説明していきます。

目次

MPFRによる拡張

 GNU AWKをソースからビルドする際、GNU MPFRとGNU MPがすでに導入されている場合には、自動的にMPFR拡張が導入されます。導入されているかどうかは、gawkのバージョンを表示することで分かります。次のように表示されたバージョンは、この拡張が組み込まれています。

$ gawk --version
GNU Awk 4.1.60, API: 1.1 (GNU MPFR 3.1.2, GNU MP 5.1.2)

 この拡張が組み込まれていない場合には、「(GNU MPFR 3.1.2, GNU MP 5.1.2)」という部分が含まれません。ここでは、この拡張が組み込まれているとして進めていきます。

 最も簡単にMPFRによる拡張機能を用いる方法は、gawkの起動オプションで-Mを指定することです。

 このMPFRによる拡張機能が組み込まれていないgawkでは53ビットまでの数値を扱えます。これは、次のような例で試すことができます。

$ echo 53 | gawk '{print 2 ^ $1 - 1}'
9007199254740991

$ echo 54 | gawk '{print 2 ^ $1 - 1}'
18014398509481984

 2のべき乗は必ず偶数になるため、これから1を引いた数は奇数になるはずですが、2 ^ 54 - 1が偶数になっていることが分かります。これはgawkが53ビット演算までしか正確に計算できていないということです。そこで今度はMPFRを用いた拡張を試してみましょう。

$ echo 54 | gawk -M '{print 2 ^ $1 - 1}'
18014398509481983

 検算はbcコマンドで行ってみましょう。

$ echo '2^54-1' | bc
18014398509481983

 このように正しく演算を行うことが可能になります。

 また同様に、従来のgawkでは非常に小さな数は0として出力されていましたが、MPFRの拡張を用いることで、そのままの数値で扱うことも可能になります。

$ gawk 'BEGIN {x = 1.0e-400; print x + 0}'
0

$ gawk -M 'BEGIN {x = 1.0e-400; print x + 0}'
1e-400

 

AWKでls

 AWKはシェルを介した他のコマンドとの相性が良いため、「シェル芸勉強会」の中でも毎回用いられるコマンドの1つです。しかし、基本的なコマンドほどOS間で出力形式が微妙に異なるため、悩まされたことも多いのではないかと思います。そこで、lsコマンドそのものを作ってみます。

@load "filefuncs"

BEGIN {

    passwd = "/etc/passwd";
    group = "/etc/group";

    FS = ":";

    while (getline < passwd > 0) {
        user_of[$3] = $1;
    }
    close(passwd);

    while (getline < group > 0) {
        group_of[$3] = $1;
    }
    close(group);

    for (i = 1; i <= ARGC - 1; i++) {
        stat(ARGV[i], stat_data_of);

        m_time = strftime("%Y-%m-%d %H:%M", stat_data_of["mtime"]);

        printf("%s %3d %8s %8s %9d %s %s\n",
            stat_data_of["pmode"],
            stat_data_of["nlink"],
            user_of[stat_data_of["uid"]],
            group_of[stat_data_of["gid"]],
            stat_data_of["size"],
            m_time,
            stat_data_of["name"]);
    }
}

 ここで初めて登場した拡張@loadが最初の行にありますが、この@loadにより様々な拡張を行うことができます。ここでは「filefuncs」という拡張を呼び出しています。このfilefuncsによりファイル情報を直接読むことができます。

 このfilefuncsではstat()関数が加えられ、このstat()関数の第1引数のファイルの情報が、第2引数の配列に格納されます。また、フォーマットをlsコマンドらしくするため、/etc/passwdファイルと/etc/groupファイルの中身を調べてuidとgidを取得しています。

 では、実行してみましょう。

$ touch a b

$ gawk -f ls.awk a b
-rw-r--r--   1 hi_saito hi_saito         0 2014-11-03 15:18 a
-rw-r--r--   1 hi_saito hi_saito         0 2014-11-03 15:18 b

$ ls -l --time-style=long-iso a b
-rw-r--r-- 1 hi_saito hi_saito 0 2014-11-03 15:18 b
-rw-r--r-- 1 hi_saito hi_saito 0 2014-11-03 15:18 a

 このようにGNUのcoreutilsのlsコマンド(--timestyle=long-isoオプション相当)に近い出力を得ることができました。

本連載が単行本になりました!

「シェル芸」に効く!AWK処方箋

Amazon  その他

「シェル芸」に効く!AWK処方箋

著者:斉藤博文
発売日:2017年1月31日(火)
価格(POD):2,160円(税込)
価格(電子書籍):1,728円(税込)

本書について

 コマンドであり軽量言語(LL)の元祖でもあって、シェルでのテキストデータ処理には便利で手放せない「AWK」の魅力と書き方、シェルコマンドと組み合わせたテクニック(シェル芸)を解説。
 プリントオンデマンド(POD)と電子書籍にて、絶賛発売中です!


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 斉藤 博文(サイトウヒロフミ)

    最初にAWKと出会ってから○十年、AWKの魅力に取りつかれ、勢い余って「日本 GNU AWKユーザー会」を立ち上げています。会としてOSCなどのイベントにも出展しつつ、GNU AWKの開発も手伝っています。「USP友の会」では幹事役ですが、「シェル芸勉強会」にはほぼ毎回参加して一緒に勉強しています。...

バックナンバー

連載:シェルスクリプトマガジン コラボレーション連載/「シェル芸」に効く GNU AWK処方箋
All contents copyright © 2005-2017 Shoeisha Co., Ltd. All rights reserved. ver.1.5