SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

USP MAGAZINEコラボレーション連載/「シェル芸」に効く AWK処方箋

AWKプログラミングの真髄の1つ
フィールド(列)を操る基礎テクニック

► 「シェル芸」に効く AWK処方箋 第3回 (月刊『USP MAGAZINE 2014 June (Vol.14)』より転載)


範囲指定でフィールドを抜き出す

 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 2014 July(Vol.15)』は、ただいま絶賛発売中!
USP MAGAZINE 2014 July(Vol.15)

 『USP MAGAZINE』は日本で唯一のシェルスクリプト総合誌(毎月25日発売)。最新号 2014 July(Vol.15)の巻頭特集は「愛されデータサイエンティスト」! 現場で役立つ、愛されるデータサイエンティストになるための3つのコツを探ります。平愛美さんの新連載、Linux女子部誌上講座「リナ女のたしなみ」では、Linuxでの写真管理についてわかりやすく解説!「金融システムにおけるUNIXの歩み」では、未知なる技術へのチャレンジが新しい価値を生むという、筆者の千貫さんのご体験をつづっていただきました。15~20年前からシェルもAWKも大活躍! 好評連載のシェル芸勉強会後追い企画「Haskellでやってはいかんのか」、AWK処方箋の第4回なども掲載です!

 

► お求めは、Amazon.co.jpUSP研究所のWebサイト取り扱い書店まで。

 

USP MAGAZINE 2014 July(Vol.15)

価格:500円+税

仕様:B5版 64ページ オールカラー

発行人:ユニバーサル・シェル・プログラミング研究所

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
USP MAGAZINEコラボレーション連載/「シェル芸」に効く AWK処方箋連載記事一覧

もっと読む

この記事の著者

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

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

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/7852 2017/01/31 20:02

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー