Table of Contents
テキスト処理が得意なプログラミング言語 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
次のように結果が表示されたでしょうか。
実行結果
banana
lemon
各行を半角スペースで区切った時の1つ目の単語が表示されています。次のように、プログラムの $1 を $2 に書き換えて実行するとどうなるでしょうか。
awk '{print $2}' test.txt
実行結果
120
90
今度は各行の2つ目の単語が表示されています。このように、awkはファイルや標準入力から1行ずつデータを読み込み、そこに含まれる区切り文字(デフォルトでは半角スペース)でデータを自動的に分割して処理を行います。
ちなみにawkでは、行のことをレコードと呼びます。つまりawkでは、1レコードずつデータを読み込んで処理を行うということです。
awkのプログラム
awkのプログラムは次のような構成になっています。
awk '{命令}' 読み込むファイルのパス
区切り文字で分けられる一部分のことをフィールドと呼びます。先ほどの例では、1つの行(レコード)の中に3つのフィールドが含まれています。
フィールドを表示するために print という命令を使います。print の後に $フィールド番号 と書くことで特定のフィールドを表示できます。次のようにカンマで区切って複数指定することもできます。
awk '{print $1, $3}' test.txt
実行結果
banana fruit
lemon fruit
これで、各レコードの1つ目と3つ目のフィールドを出力することができます。
print では普通の文字列も出力させることができます。文字列はダブルクオーテーション(”)で囲み、文字列とフィールドを組み合わせる場合はカンマ(,)で区切ります。
awk '{print "An", $1, "is a", $3}' test.txt
実行結果
An banana is a fruit
An lemon is a fruit
カンマで区切った場合、デフォルトでは半角スペースが間に挿入されます。カンマで区切らなかった場合、以下のように文字列が繋がって表示されます。
awk '{print "An" $1 "is a" $3}' test.txt
実行結果
Anbananais afruit
Anlemonis afruit
awkのプログラムで得られた結果を他のUnixコマンドに渡して処理する例を示します。次の例では、得られた結果をアルファベットの逆順に並べて表示します。
awk '{print $1, $3}' test.txt | sort -r
実行結果
banana fruit
apple fruit
フィールドの区切り文字を指定する
-Fオプションを使用すると、スペース以外を区切り文字として扱うことができます。-Fと書いた直後に区切り文字にしたい文字を書きます。次の例では “,”(カンマ)を区切り文字として読み込みます。
test2.txt
tomato,100,vegetable milk,80,beverage tea,50,beverage
入力するコマンド
awk -F, '{print $1, $3}' test2.txt
実行結果
milk beverage
tea beverage
出力される結果の区切り文字も変更したい場合は -vオプションを使用します。このオプションは変数に値をセットするために使われます。出力の区切り文字は OFS をという変数にセットします。
awk -F, -v 'OFS=:' '{print $1, $3}' test2.txt
実行結果
milk:beverage
tea:beverage
awkで使われる特殊な変数
awkで特別な意味をもつ変数を紹介します。
NF
Number of Field(フィールド数)の略です。処理をするレコードに存在するフィールドの数がこの変数の中に入っています。例として先ほど使った test2.txt でNFを使ってみます。
awk -F, '{print NF}' test2.txt
実行結果
3
3
test2.txt に書かれているレコードは、すべて3つのフィールドを持っています。その数 3 が NF、つまり NF = 3 となります。ですので、もしフィールドが 5 つであるなら NF は 5 となります。
この変数の頭に $ をつけて $NF として使うことが出来ます。このようにすると、以下のような使い方ができます。
awk -F, '{print $NF}' test2.txt
実行結果
beverage
beverage
この結果からわかることは、$NF が $3 と同じになっているということです。レコードの最後のフィールドだけを取り出したい場合に便利です。
NF は最後のフィールドを指す場合に便利です。
$0
$0 は全てのフィールドを表します。
awk -F, '{print $0}' test2.txt
実行結果
milk,80,beverage
tea,50,beverage
条件を指定して処理を行う。
命令を書いている部分の直前に条件文を書くことができます。例を見てみましょう。
awk -F, '$2 <= 90 {print $1, "は90以下"}' test2.txt
実行結果
tea は90以下
この例では、2つ目のフィールドの値が90以下だった場合に命令を実行します。
値が等しいかどうかのチェックは “=” ではなく “==” ですので注意してください。例えば、2つ目のフィールドが80であるものだけを表示したい場合は次のようにします。
awk -F, '$2 == 80 {print $1, "は80"}' test2.txt
実行結果
練習問題
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
win10でawkをインストールする方法を教えてください
記事をご覧いただきありがとうございます。
Windows10 ではBash on Ubuntu on Windows 上で awk を使用することができます。
Bash on Ubuntu on Windows の設定方法については以下の記事をご覧いただければと思います。
Windows10でBashを動かす方法(Bash on Ubuntu on Windows の設定)
ピンバック: Windows10でBashを動かす方法(Bash on Ubuntu on Windows の設定) | JoyPlotドキュメント