範囲指定でフィールドを抜き出す
AWKで指定範囲のフィールドを抜き出すには、for文やwhile文のようなループを用いる必要があり、複雑になります。
まず、for文を用いた例を示します。
$ echo "a b c" | \\
awk '{for (i = 2; i <= NF; i++) a = a OFS $i; print a}'
b c
または、while文を使って以下のようにも記述できます。
$ echo "a b c" | \\
awk '{i = 2; while (i <= NF) a = a OFS $(i++); print a}'
b c
ここで、a = a OFS $i や a = a OFS $(i++) という記述がありますが、AWKでは文字列同士を繋げるには連続して記述します。
また、$i++と記述すると、AWKの演算の優先順位により、$iに対してインクリメント演算子(++)が実行されてしまうため、変数iに対してインクリメントするように括弧で囲んでいます。
フィールドの計算
よく行う処理として、フィールドの計算があります。いわゆる縦横集計の横方向の集計にあたります。これを行うにはfor文を使います。
$ echo "1 2 3" | \\
awk '{for (i = 1; i <= NF; i++) sum += $i; print sum}'
6
ちょっと長いですね。行数が多くなければ、「シェル芸」を使うといろいろな計算方法が使えます。例として、計算式を生成してbcコマンドに投げる方法を示します。
$ echo "1 2 3" | tr ' ' '+' | bc 6
これは、bashの配列$PIPESTATUS[@]が全て0かどうかを判断するときに、筆者がよく使っている手法の一つです。
では、AWKを用いる利点にはどのようなものがあるのでしょうか。以下のような点が挙げられます。
- Cライクな文法で統一して記述できる。
- 他のコマンドに頼ることなく全てをAWKだけで完結できる。
- 処理が速い。
「AWKは遅い」と思われているようですが、一般的なディストリビューションで用いられているmawkやgawkは、他のインタプリタ言語よりも高速に動作します。それに加えて、パイプを多段にすることによる時間的なロスも少なくできます。AWKでも簡潔に記述できる場合には、AWKで記述することをお勧めします。
もう一例として、体重(kg)と身長(cm)が与えられたときのBMI値を計算してみます。
$ echo "50 160" | awk '{print $1 / ($2 / 100) ^ 2}'
19.5312
別の機会に数値演算についても説明していきますが、AWKは四則演算だけでなく一般的な数学関数も扱うことができるため、さまざまな計算を行うことが可能です。
フィールドの再構築
最後に「フィールドの再構築」という、聞きなれないAWK独自の書式の説明をします。
例えば、CSVファイルをスペース区切りにしたいとしましょう。つまり、組込変数FSにカンマを指定して、組込変数OFS にスペースを指定すれば良いわけです。
$ echo "a,b,c" | awk -F',' -v OFS=' ' '4'
変わりませんね。これは、"a,b,c"を読み込んだ際にAWKがフィールド分割を行っているだけで、新しくフィールドを再構築していないためです。
新しくフィールドを再構築し、新しいレコードを作成するには、次のような変わった文法を用います。
$ echo "a,b,c" | awk -F',' -v OFS=' ' '$1 = $1'
この「$1 = $1」という記述方法をフィールドの再構築と呼び、全てのAWKで通用する記法となっています。
AWKは、フィールドに新しく変数が代入された場合にはじめて組込変数OFSにしたがって、フィールドとレコードを再構築します。
すでに学習したように、代入された結果が偽(左辺値がゼロまたは空文字列)になると成立しません。
$ echo "0,1,2" | \\ awk -F',' -v OFS=' ' '$1 = $1' ←何も表示されない
そういう場合には、パターンで記述せずにアクションで記述すると安心です。
$ echo "0,1,2" | \\
awk -F',' -v OFS=' ' '{$1 = $1; print}'
0 1 2
フィールドの再構築を行うことで、簡単にさまざまなフォーマットへの変換ができます。
知らないと、$1 = $1という記述は何をやっているのかすら分からないのですが、慣れると便利です。フォーマット変換はAWKの武器の1つですので、覚えておくとシェル芸がはかどることでしょう。
『USP MAGAZINE』は日本で唯一のシェルスクリプト総合誌(毎月25日発売)。最新号 2014 July(Vol.15)の巻頭特集は「愛されデータサイエンティスト」! 現場で役立つ、愛されるデータサイエンティストになるための3つのコツを探ります。平愛美さんの新連載、Linux女子部誌上講座「リナ女のたしなみ」では、Linuxでの写真管理についてわかりやすく解説!「金融システムにおけるUNIXの歩み」では、未知なる技術へのチャレンジが新しい価値を生むという、筆者の千貫さんのご体験をつづっていただきました。15~20年前からシェルもAWKも大活躍! 好評連載のシェル芸勉強会後追い企画「Haskellでやってはいかんのか」、AWK処方箋の第4回なども掲載です!
► お求めは、Amazon.co.jp、USP研究所のWebサイト、取り扱い書店まで。
USP MAGAZINE 2014 July(Vol.15)
価格:500円+税
仕様:B5版 64ページ オールカラー
発行人:ユニバーサル・シェル・プログラミング研究所
