次に挙げる例は、入力されたデータ中の各単語の出現回数を出力する完全な
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
コマンドの使い方をもっと詳しく知りたいのならばオペレーティングシ
ステムのドキュメントを参照すること。