簡単で、奥深くて、超便利!
LLの元祖「AWK」にさわってみよう
► 「シェル芸」に効く AWK処方箋 第1回 (月刊『USP MAGAZINE 2014 April(Vol.12)』より転載)
USP友の会で開催している「シェル芸勉強会編注1」では必ずといって良いほどAWKが登場します。それを受けて本連載では「シェル芸」をターゲットとしたAWKの活用方法を紹介していきます。記事では特にAWKの基礎的な部分について深く掘り下げます。AWKの初心者から上級者まで納得できる内容を目指しますので、本稿をきっかけに多くの方がAWKに慣れ親しんでくれると幸いです。
編注1:「シェル芸」とは、UNIXシェル(主にbash)のワンライナーを駆使して文字列加工を自由自在に操ることです。また、そのような能力をもつ人をシェル芸人と呼びます。
パターンとアクション
AWKはパターンとアクションを組み合わせるプログラム言語です。日本語で「もし○○だったら、○○をする」という文章のうち、「もし○○だったら」という部分がパターンであり、「○○する」という部分がアクションです注1。このようにパターンとアクションで構成されるAWKの基本文法は直感的であるため、様々な機会で用いられます。これをAWKスクリプトで記述すると以下のようになります。
パターン {アクション}
さて、「パターン」という名前から「正規表現にマッチする」ようなイメージを持たれるかもしれませんが、AWKのパターンは「条件式」そのものであり、その条件式の戻り値による「真偽」にしたがいアクションが実行されます。今回はこのパターンの真偽について深く掘り下げていきます。
AWKはパターンとアクションはそれぞれ省略することができます。パターンを省略した場合には全てのレコードに対しアクションが実行され、アクションが省略された場合にはパターンにマッチしたレコードを表示するという便利な省略を行うことができます。
したがって、パターンの真偽をうまく活用することでAWKらしく簡潔に記述することができるため、AWKの真偽を正しく理解することはとても重要になってきます。
注1 最近2つのWebサービスを連携させるIFTTT (https://ifttt.com/) というサービスがありますが、まさに「パターンとアクション」で構成されている例と言えるでしょう。
AWKの真偽って何?
さて、AWK の真偽はどのように判定されているのでしょうか。AWKにはTRUEやFALSEといったブール値というものは存在しません。そこで、AWKは以下のようにして判定しています。
- 数字の0(ゼロ)は「偽」となります。
- 空の文字列は「偽」となります。
- 上記以外は全て「真」となります。
これだけです。AWKには「型」がないにも関わらず、数字とか文字列とか書かれているのは不思議に思われるかもしれませんが、故意に型を変換することで真偽を自在に操ることができるのです。
では、実際に試してみましょう。前述のようにアクションがない場合にはレコードをそのまま表示しますので、「数字の0」(「文字列の"0"」ではない点に注意してください)をパターンに指定してみます。
$ echo "foo" | awk '0'
何も表示されませんね。では、「数字の4」を入れてみましょう。
$ echo "foo" | awk '4' foo
数字の1でも何でも数字の0以外であれば構わないのですが、他の文字との読み違えを防ぐため、AWK界隈では数字の4が好まれる傾向にあります。では、文字列の場合はどうでしょうか。
$ echo "foo" | awk '"bar"' foo
パターンが文字列"bar"というのはとても変ですが、先ほど述べたとおり、空の文字列ではないため「真」となり、パイプで渡されたレコードがそのまま表示されています。この文字列"bar"は正規表現ではなく文字列として扱われる点に注意してください。
AWKの真偽はこれが全てです。簡単ですが、さらに理解を深めることで様々な条件分岐をエレガント注2に行うことができます。
注2:AWK使いは「エレガント」という言葉を好んで使います。
比較演算子、マッチング演算子
AWKにはC言語のような比較演算子があり、数値も文字列も同様に扱うことができます。例えば以下のようなものです。
$ echo "foo" | awk '$0 == "foo"' foo
さて、この比較演算子は何を返しているのでしょうか。print文で確かめてみましょう。
$ echo "foo" | awk '{print $0 == "foo"}'
1
$ echo "foo" | awk '{print $0 != "foo"}'
0
つまり、比較演算子の真は数字の1で、偽は数字の0を返しています。
さらに、AWKには正規表現にマッチするかどうかを判定するマッチング演算子もあります。こちらも見てみましょう。
AWKの中で単独で「/」で囲まれた正規表現が用いられた場合には「$0 ~」が省略されたものと見なされます注3ので、以下のように記述することもできます。
$ echo "foo" | awk '/foo/' foo
さて、どのように真偽の判定をしているのか見てみましょう。
$ echo "foo" | awk '{print /foo/}'
1
$ echo "foo" | awk '{print !/foo/}'
0
この記法を{print "foo"}のつもりで使ってしまって、うまく動作しなかった経験がある方もいらっしゃると思いますが、前述のように「$0 ~」が省略されているため、戻り値は数字の0または数字の1なのです。このように、比較演算子やマッチング演算子は数字の0または数字の1で判定されていることが分かります。
注3:この省略はパターンのみに有効だと思われている方が多いのですが、AWKの組込関数で使われる場合以外の全てで有効な省略です。
本連載が単行本になりました!
この記事は参考になりましたか?
- USP MAGAZINEコラボレーション連載/「シェル芸」に効く AWK処方箋連載記事一覧
- この記事の著者
-
斉藤 博文(サイトウヒロフミ)
最初にAWKと出会ってから○十年、AWKの魅力に取りつかれ、勢い余って「日本 GNU AWKユーザー会」を立ち上げています。会としてOSCなどのイベントにも出展しつつ、GNU AWKの開発も手伝っています。「USP友の会」では幹事役ですが、「シェル芸勉強会」にはほぼ毎回参加して一緒に勉強しています。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア

