次に挙げる例は、入力されたデータ中の各単語の出現回数を出力する完全な
awkプログラムである。これはまた、`for x in array'と
いう記述の例でもある。最終的に、複雑であるが有効な仕事を最小限の労力で行なう
ために、 awkとほかのユーティリティプログラムと組み合わせる事ができる
という例でもある。説明はプログラムのあとに書かれている。
awk '
# 単語の使用頻度をリストアップする
{
for (i = 1; i <= NF; i++)
freq[$i]++
}
END {
for (word in freq)
printf "%s\t%d\n", word, freq[word]
}'
このプログラムは二つのルールを持っている。最初のルールはパターンを持ってい
ないので、入力された全ての行に対して実行される。このプログラムでは入力行中
の独立した単語を取り出すためにawkのフィールドアクセス機構
(セクション フィールドの検査を参照) を使用し、フィールドが幾つ存在
しているのかを知るために組み込み変数NFを使って得ている
(セクション 組込み変数を参照)。
入力単語ごとに、配列変数freqの要素はその単語が現れたということを反映
するためにインクリメントされる。
二番目のルールはENDというパターンを持っているので入力が尽きるまでは
実行されない。このルールでは最初のアクション部で作成されたテーブル
freqの内容を出力する。
このプログラムは、実際のテキストファイルに使用するにはいくつかの問題点があ る。
awkのコンベンション−入力中の空白とそれ以外のキャラクタ
(改行を除く)とで分割し、入力がawkに対して特殊な意味を持つものでな
い−を使用して行なっている。これは句読点のキャラクタも単語の一部として数え
られてしまうということである。
awk言語では、ある文字の大小文字は区別される。したがって、`foo' と
`Foo'はこのプログラムでは同じものとしては扱われない。このことは普通の
テキストでは好ましくないものである。なぜならセンテンスの始まりにある単語は
大文字にされ、先のスクリプトはそういったものを区別して扱ってしまうからであ
る。
これらの問題を解決する方法は、awk言語の機能を使用するということであ
る。第一に、大小文字の区別を無くすためにtolowerを使う。次に、句読点
のキャラクタを取り除くためにgsubを使う。最後に、awkスクリプト
の出力を処理するために sortユーティリティを使う。ということである。
まず初めに新しいバージョンのプログラムを次に挙げよう。
awk '
# Print list of word frequencies
{
$0 = tolower($0) # 大小文字の違いをなくす
gsub(/[^a-z0-9_ \t]/, "", $0) # 句読点を取り除く
for (i = 1; i <= NF; i++)
freq[$i]++
}
END {
for (word in freq)
printf "%s\t%d\n", word, freq[word]
}'
ここではこのプログラムが`frequency.awk'という名前のファイルに格納され ていて、データが`file1'にあるとして、次のようにする。
awk -f frequency.awk file1 | sort +1 -nr
このパイプラインは`file1'中に出てくる単語を出現回数の多い順に並んだテ ーブルを作り出す。
awkは入力順ではなく適当な順番で、(単語の)データと単語の頻度テーブル
を出力する。
awkスクリプトの出力はsortコマンドによってソートされターミナル
に出力される。この例ではsortコマンドに対し、入力行の二番目のフィール
ドを使い(フィールドをひとつスキップする)、それを数値を表わすものとして(そう
しないと`15' が`5'の前に来てしまう)、ソートを降順(逆順、大きい順)
で行なうようにオプションで指定している。
sortをプログラムの中から使うこともでき、それには ENDアクショ
ンを次のように変更すれば良い。
END {
sort = "sort +1 -nr"
for (word in freq)
printf "%s\t%d\n", word, freq[word] | sort
close(sort)
}'
sortコマンドの使い方をもっと詳しく知りたいのならばオペレーティングシ
ステムのドキュメントを参照すること。