歴史の荒波を越えて使い続けられるツールがあります。テキスト処理で使われる歴史あるスクリプト言語AWK(オーク)は間違いなくその一つです。大抵のUNIX/LinuxをはじめmacOSにも最初からインストールされておりWindowsでも使えます。今回は、時代を超えて愛されるスクリプト言語AWKの魅力に迫ってみましょう。
AWKとは
AWKは主にテキスト処理に使われるスクリプト言語です。1977年にUNIX開発の過程で生まれました。「AWK」の名前の由来は、開発者のアルフレッド・エイホ、ピーター・ワインバーガー、ブライアン・カーニハンの3人の苗字の頭文字からとられています。
AWK最大の特徴は、CSV形式などのテキストデータを手軽に処理できることです。テキスト処理に特化していることから、簡単なスクリプトを書くだけで、本格的な仕事をこなすことができるのが特徴です。もちろん、汎用的なスクリプト言語としての機能も備えていることから、元祖軽量スクリプト言語としてさまざまな現場で利用されました。
なお、AWKは2022年2月のTIOBE Indexでもベスト50以内にランクインしています。誕生から45年経った現在でも現役です。
AWKをインストールしよう
【Windowsの場合】
WindowsでAWKを使おうと思った場合、Windows用のAWK(Gawk for Windows)が用意されています。これをインストールするのも便利ですが、Windows上でLinuxが使えるWSLを使うのが簡単です。
WSLでUbuntuなどをインストールすれば、最初からawkコマンド(gawk)が使えます。Windows 10/11でWSL Ubuntuをインストールするには、PowerShellで以下のコマンドを実行します。
wsl --install
そして、Microsoft Storeを起動し、Ubuntuなどのディストリビューションを検索してインストールします。Ubuntuを起動して、gawkとタイプすると使い方が表示されます。
【macOSの場合】
macOSにも最初からAWKがインストールされていますが、BSD由来のAWKです。ここでは、GNU由来のAWKを使ってみます。Homebrewで以下のコマンドを実行すると、GNUのAWKをインストールできます。
$ brew install gawk
AWKの簡単な使い方
AWKが便利な点として、コマンドライン上で簡単なコマンドを記述するだけで多くの仕事がこなせる点にあります。例えば、簡単なテキスト処理の例として、CSVファイルを処理してみましょう。
次のようなCSVファイルを用意しました。これは、あるレストランで顧客が注文した商品をCSV形式で表したもので、「order.csv」というファイル名で保存しましょう。
商品番号, 商品名, 個数, 値段
A001, ビーフバーガー, 2, 820
A002, たっぷりポテトフライ, 1, 300
A003, ホットケーキ, 1, 560
A004, ウーロン茶, 3, 200
このCSVファイルから商品名と個数の列だけを取り出して画面に表示したいとします。その場合、次のようなコマンドを実行するだけで目的が達成できます。order.csvを配置したディレクトリで次のコマンドを実行してみましょう。
gawk -F',' '{print $2, $3}' order.csv
実際に実行すると、商品名と個数を取り出すことができました。
簡単にコマンドを確認してみましょう。「gawk」がGNU AWKを実行するコマンドです。続く「-F ','」がテキストデータの区切り文字を指定するものです。CSVファイルの区切り文字はカンマなのでこのように指定します。これに続く「'{print $2, $3}'」がAWKのプログラムです。そして、末尾のorder.csvが処理対象のデータファイルです。
AWKのプログラム部分を見ると「{ print $2, $3 }」と書いてあるだけです。AWKでは与えられたデータの一行ずつについて、特定の区切り記号で区切り、$1, $2, $3, $4...のようにアクセスできるようになっています。なお、一行全部が必要な場合は、$0と書きます。
次に、CSVファイルに記述された注文の合計金額を求めてみましょう。
gawk -F ',' '{total += $3 * $4} END {print total}' order.csv
コマンドラインで実行してみます。すると、注文の合計金額である3100を出力します。やはり一行のコマンドを入力しただけですが、バッチリ答えを出すことができました。
AWKのプログラム部分を確認してみましょう。少し読みやすく改行し、コメントを付けると次のようになります。
# 毎行処理する処理 --- (*1)
{
total += $3 * $4
}
# 毎行処理の最後に実行する処理 --- (*2)
END {
print total
}
AWKのプログラムでは、データファイルを毎行処理する処理、毎行処理の最後に実行する処理(END)、毎行処理の最初に実行する処理(BEGIN)を記述できます。それで(1)の毎行処理の部分では毎行処理する部分で、3列目と4列目の値を掛け合わせ、変数totalに足すという処理を記述します。そして、(2)の毎行処理の最後では変数totalの内容を画面に出力するというものになっています。
これだけ見ても、CSVファイルなど改行ごとに区切られたテキストデータを扱うのに敵なしの状態であることが分かると思います。CSVファイルを集計するプログラムを他のスクリプト言語で書いたらもっと長いものになってしまうでしょう。
FizzBuzz問題を解いてみよう
それでは、本連載恒例のFizzBuzz問題をAWKで解いてみましょう。FizzBuzz問題とは次のようなプログラムです。
> 1から100までの数を出力するプログラムを書いてください。ただし、3の倍数のときは数の代わりに「Fizz」と、5の倍数のときは「Buzz」と表示してください。3と5の倍数の時は「FizzBuzz」と表示してください。
AWKの機能だけを使ってオーソドックスなFizzBuzzのプログラムを書くと次のようになるでしょう。
BEGIN {
for (i = 1; i <= 100; i++) {
if (i % 3 == 0 && i % 5 == 0) {
print "FizzBuzz"
} else if (i % 3 == 0) {
print "Fizz"
} else if (i % 5 == 0) {
print "Buzz"
} else {
printf "%d\n", i
}
}
}
このプログラムを「fizzbuzz.awk」という名前で保存したら、以下のコマンドを実行しましょう。
gawk -f fizzbuzz.awk
実行すると次のように表示されます。AWKのプログラムはC言語やそれに影響を受けた言語に似ているため、比較的読みやすく感じるのではないでしょうか。
なお、「seq」コマンドと組み合わせて使ってみましょう。seqとAWKを組み合わせれば、少し長いものの1行(ワンライナー)で、FizzBuzz問題を解くことができます。
seq 100 | gawk '$1%15==0{print "FizzBuzz";next} $1%3==0{print"Fizz";next} $1%5==0{print "Buzz";next}{printf "%d\n",$1}'
コマンドを実行すると、FizzBuzz問題の答えが表示されます。
まとめ
以上、今回はAWKについて紹介しました。実際にCSVファイルを読み込んで処理するスクリプトを紹介しましたが、テキスト処理のプログラムが驚くほど簡単に記述できると感じたのではないでしょうか。今なお現役で使われているのも納得です。時代を超えて愛されるスクリプト言語のAWKは、サーバー管理や、コマンドラインをよく使う人にとっては必須のツールの一つです。比較的習得も容易なので覚えておくと便利でしょう。
自由型プログラマー。くじらはんどにて、プログラミングの楽しさを伝える活動をしている。代表作に、日本語プログラミング言語「なでしこ」 、テキスト音楽「サクラ」など。2001年オンラインソフト大賞入賞、2004年度未踏ユース スーパークリエータ認定、2010年 OSS貢献者章受賞。技術書も多く執筆している。直近では、「シゴトがはかどる Python自動処理の教科書(マイナビ出版)」「すぐに使える!業務で実践できる! PythonによるAI・機械学習・深層学習アプリのつくり方 TensorFlow2対応(ソシム)」「マンガでざっくり学ぶPython(マイナビ出版)」など。