テキスト処理が得意なプログラミング言語 awk入門

By | 2016年8月1日

テキスト処理が得意なプログラミング言語 awk

シェルスクリプトと組み合わせることで様々な処理を実現できるプログラミング言語 awk について簡単に紹介します。特に何かを新たにインストールする必要がなく、今まで紹介してきたシェルスクリプトを実行できる環境が整っているならすぐに使えます。

Windows10 で使用する場合は、Bash/WSLの設定を行ってください。Bash/WSLの設定方法については以下の記事をご覧ください。

Windows10でBashを動かす方法(Bash on Ubuntu on Windows の設定)

awkの使用例

まず、最も簡単な使用例を示します。テキストファイル test.txt から文字列を読み込み、処理を行うプログラムです。

読み込む test.txt をカレントディレクトリに作り、中身を次のようにしてください。文字列と数字の間は半角スペースです。

test.txt

    apple 100 fruit
    banana 120 fruit
    lemon 90 fruit
  

テキストファイルが用意できたら、以下のコマンドを入力してください。

    awk '{print $1}' test.txt
  

次のように結果が表示されたでしょうか。

実行結果

apple
banana
lemon

各行を半角スペースで区切った時の1つ目の単語が表示されています。次のように、プログラムの $1 を $2 に書き換えて実行するとどうなるでしょうか。

    awk '{print $2}' test.txt
  

実行結果

100
120
90

今度は各行の2つ目の単語が表示されています。このように、awkはファイルや標準入力から1行ずつデータを読み込み、そこに含まれる区切り文字(デフォルトでは半角スペース)でデータを自動的に分割して処理を行います。

ちなみにawkでは、行のことをレコードと呼びます。つまりawkでは、1レコードずつデータを読み込んで処理を行うということです。

awkのプログラム

awkのプログラムは次のような構成になっています。

    awk '{命令}' 読み込むファイルのパス
  

区切り文字で分けられる一部分のことをフィールドと呼びます。先ほどの例では、1つの行(レコード)の中に3つのフィールドが含まれています。

フィールドを表示するために print という命令を使います。print の後に $フィールド番号 と書くことで特定のフィールドを表示できます。次のようにカンマで区切って複数指定することもできます。

    awk '{print $1, $3}' test.txt
  

実行結果

apple fruit
banana fruit
lemon fruit

これで、各レコードの1つ目と3つ目のフィールドを出力することができます。

print では普通の文字列も出力させることができます。文字列はダブルクオーテーション(")で囲み、文字列とフィールドを組み合わせる場合はカンマ(,)で区切ります。

    awk '{print "An", $1, "is a", $3}' test.txt
  

実行結果

An apple is a fruit
An banana is a fruit
An lemon is a fruit

カンマで区切った場合、デフォルトでは半角スペースが間に挿入されます。カンマで区切らなかった場合、以下のように文字列が繋がって表示されます。

    awk '{print "An" $1 "is a" $3}' test.txt
  

実行結果

Anappleis afruit
Anbananais afruit
Anlemonis afruit

awkのプログラムで得られた結果を他のUnixコマンドに渡して処理する例を示します。次の例では、得られた結果をアルファベットの逆順に並べて表示します。

    awk '{print $1, $3}' test.txt | sort -r
  

実行結果

lemon fruit
banana fruit
apple fruit

フィールドの区切り文字を指定する

-Fオプションを使用すると、スペース以外を区切り文字として扱うことができます。-Fと書いた直後に区切り文字にしたい文字を書きます。次の例では ","(カンマ)を区切り文字として読み込みます。

test2.txt

    tomato,100,vegetable
    milk,80,beverage
    tea,50,beverage
  

入力するコマンド

    awk -F, '{print $1, $3}' test2.txt
  

実行結果

tomato vegetable
milk beverage
tea beverage

出力される結果の区切り文字も変更したい場合は -vオプションを使用します。このオプションは変数に値をセットするために使われます。出力の区切り文字は OFS をという変数にセットします。

    awk -F, -v 'OFS=:' '{print $1, $3}' test2.txt
  

実行結果

tomato:vegetable
milk:beverage
tea:beverage

awkで使われる特殊な変数

awkで特別な意味をもつ変数を紹介します。

NF

Number of Field(フィールド数)の略です。処理をするレコードに存在するフィールドの数がこの変数の中に入っています。例として先ほど使った test2.txt でNFを使ってみます。

    awk -F, '{print NF}' test2.txt
  

実行結果

3
3
3

test2.txt に書かれているレコードは、すべて3つのフィールドを持っています。その数 3 が NF、つまり NF = 3 となります。ですので、もしフィールドが 5 つであるなら NF は 5 となります。

この変数の頭に $ をつけて $NF として使うことが出来ます。このようにすると、以下のような使い方ができます。

    awk -F, '{print $NF}' test2.txt
  

実行結果

vegetable
beverage
beverage

この結果からわかることは、$NF が $3 と同じになっているということです。レコードの最後のフィールドだけを取り出したい場合に便利です。

NF は最後のフィールドを指す場合に便利です。

$0

$0 は全てのフィールドを表します。

    awk -F, '{print $0}' test2.txt
  

実行結果

tomato,100,vegetable
milk,80,beverage
tea,50,beverage

条件を指定して処理を行う。

命令を書いている部分の直前に条件文を書くことができます。例を見てみましょう。

    awk -F, '$2 <= 90 {print $1, "は90以下"}' test2.txt
  

実行結果

milk は90以下
tea は90以下

この例では、2つ目のフィールドの値が90以下だった場合に命令を実行します。

値が等しいかどうかのチェックは "=" ではなく "==" ですので注意してください。例えば、2つ目のフィールドが80であるものだけを表示したい場合は次のようにします。

    awk -F, '$2 == 80 {print $1, "は80"}' test2.txt
  

実行結果

milk は80

練習問題

awkを使って、以下の条件を満たすシェルスクリプトを作ってください。

  • 次のような内容の practice.txt というファイルを読み込む。(このファイルは普通にテキストエディタで作る)
            10 apple is fantastic
            20 banana is excellent
            30 peach is marvelous
          
  • practice.txtを読み込み、実行結果が以下のようになるようプログラムを実行せよ。ただし、プログラム中では $1, $2, $3, $FN の4つの変数と、数値の20を使用すること。
    excellent is banana!
答えの例(クリックで開く)
      #!/bin/bash

      awk '$1 == 20 {print $NF, $3, $2 "!"}' practice.txt
    

テキスト処理が得意なプログラミング言語 awk入門」への3件のフィードバック

  1. ピンバック: Windows10でBashを動かす方法(Bash on Ubuntu on Windows の設定) | JoyPlotドキュメント

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です