更新

AWKプログラミング(応用編)

小山智史

(入門編)
1. 準備
2. AWK言語とプログラムの実行
3. 簡単なAWKプログラム
4. データの型と変数 5. 演算
6. 入出力
7. 関数
8. 条件分岐: if文
9. 繰り返し: while文とfor文
10. 配列と連想配列
11. 関数: 再帰による関数定義
12. 文字列の処理と正規表現
13. 乱数の利用
付録A. AWK言語のまとめ

(応用編)
14. BMI早見表
15. 文書整形
16. 順序機械: 自動販売機
17. 教材分析
18. ゲームとパズル
19. 対話型学習ソフト

14. BMI早見表

 基礎編で度々登場したBMIですが、ここではBMIの早見表を作ってみます。身長と体重を変えながら、BMIを計算して表にします。

 以下は、2cm/2kg刻みにし、AWKプログラムでHTMLファイルを作り、ブラウザで表示させたものです。文字の表示色もBMIの値によって変わるようにしています。

 上記の操作は、はじめは単にAWKプログラムbmitable.awkを実行したもので、画面にHTMLコードが表示されます。次にリダイレクトでbmitable.htmlを作り、最後の操作で、ブラウザに次のような早見表が表示されます。

15. 文書整形

15.1 データの一覧表示

 sumo.csv から一覧表のHTMLファイルを作り、ブラウザに表示してみます。

 ブラウザには次のように表示されます。

15.2 定形文書の作成

 ワープロソフトの機能のひとつに「差し込み印刷」があります。定型文書の宛名の部分に住所録データから必要項目を当てはめるというような機能です。

 ここでは、次のように「雛形ファイル」を用意します。

 次のプログラムは、冒頭で上記のファイルを読み込み、1行ずつ template[ ] という配列にしまった後、sumo.csvのデータを読みながら、#1~#4の箇所を置き換えて表示します。

本文の gsub()linebufの中の#1, #2,...,#NF$1,$2,...$NFを代入し、表示しています。

実行結果は次のようになります。

(練習) 上記の定型文に、BMIの値も表示させるようにしなさい。

15.3 定型メールの受信処理

 イベントの参加申し込みなど、最近はWebのフォーム入力で行うことがほとんどかもしれませんが、メールが使われる場合もあります。

このようなメールでの案内に対して次のような返信が来てmail.txtというファイルに入っているとします。

 以下のプログラムは受け取った返信メールを処理して、「出身地,名前,身長,体重」という1件のレコード(1行データ)を生成します。

 以下、実行の様子です。最後の操作はリダイレクト「>>」でsumo.csvに「追記」しています。

 実際には記載事項に不備がないかや、二重登録でないかなど、もっと詳細にチェックします。


16. 順序機械: 自動販売機

 150円のジュース自動販売機のプログラムを作りましょう。お金は50円と100円が使えるものとします。自動販売機の内部状態としては、0円状態、50円状態、100円状態の3つが考えられます。出力はジュースまたはジュースとおつり(50円)です。この自動販売機の動作は下の図のように表すことができ、これを状態遷移図といいます。矢印は状態の遷移を表し、その矢印に付随して入力と出力を記載しています。このような機械を順序機械(または有限状態機械)といいます。


図7 自動販売機の状態遷移図

 状態遷移関数および出力関数は表5で表すことができ、表中には「次の状態/出力」が記載されています。この表を状態遷移表といいます。

表5 自動販売機の状態遷移表(表中は「次の状態/出力」)
  入力
0円50円100円
現在の状態0円0円/なし50円/なし100円/なし
50円 50円/なし100円/なし0円/ジュース
100円100円/なし0円/ジュース0円/ジュース・おつり

 データファイル juice.csv は、1番目のフィールドが現在の状態、2番目のフィールドが入力、3番目のフィールドが次の状態、4番目のフィールドが出力で状態遷移表を表しています(juice.csvはこちらからダウンロードできます)。なお、0円の入力は省略しています。このデータファイルを変更すれば、さまざまな動作をする機械を作ることができます。

 プログラムと実行の様子は以下のようになります。

(練習) 10円玉も使えるように、juice.csv を変更しなさい。


17. 教材分析

17.1 頻出単語

 英文テキストを調べ、大小文字の区別なしに、3回以上現れる単語を調べるプログラムです。tolower()は大文字を全部小文字に変換し、gsub()はアルファベット以外の数字や記号を除く処理をします。単語のカウントを行い、集計終了後に3回以上現れた単語を頻度順に表示します。

17.2 文字パターン検索

 以下の pcount.awk は、入力した正規表現にマッチする単語を探して表示するプログラムです。

^..t」は「3文字目がtの単語を探しなさい」という意味です。「e$」とすれば「最後がeで終わる単語」、「^t.*t$」とすれば「tで始まってtで終わる単語」ということになります。

(練習) 入力する「パターン」を変えて、意図した結果が得られるか試しなさい。

17.3 可読性(読みやすさ)

 ARI Readability Score は次式で与えられます(L.L.Cherry, W.Vesterman:``Writing Tools - The STYLE and DICTION Programs'',UNIX Document, USD-32.)。

 英語文書が与えられたとき、以下のプログラムは、段落や文章や単語の数、1段落の平均文数、1文の平均単語数、1単語の平均文字数、そしてARIスコアを計算し、表示します。

(練習) 英語文書が与えられたときに、単語の長さによるヒストグラムを表示するプログラムを作りなさい。

(練習) 日本語文書が与えられたときに、40文字以上「、」が現れない文章および80文字以上「。」が現れない文章を表示し、警告を与えるプログラムを作りなさい。

(練習) 疑問文や感嘆文には対応していません。これらに対応できるように拡張しなさい。

(練習) 日本語の可読性の尺度として、次式が提案されています(浅野陽子, 小川克彦:``日本文の可読性を尺度とした読みスタイルの分析'',情報処理学会ヒューマンインタフェース研究会資料, 37-7, 1991.)。例えば、小学3年レベルの文章ならば G が3、中学3年レベルの文章ならば G が9と評価されます。

これに従って、日本語文書の可読性を調べるプログラムを作りなさい。

17.4 百人一首

 hyaku.csv というファイルには「百人一首の上句、下句、作者」のデータがCSV形式で入っています。テキストエディタや表計算ソフトでこのファイルを開いて中を確認してください(hyaku.csvはこちらからダウンロードできます)。

 次のプログラムは、上句の先頭文字が「春夏秋冬」のいずれかで、作者に「天皇」を含む句を表示するというものです。

(練習) 百人一首について、別の点に着目して調べなさい。

17.5 テキスト生成

 prob27.csv にはスペース(sp)を含むアルファベット27文字の出現確率が以下のように入っています(確率データは R.I.Damper, 1984)。テキストエディタでこのファイルを開いて中を確認してください。(prob27.csvはこちらからダウンロードできます)

 以下のプログラムはこの確率でランダムに100文字のテキストを生成するものです。


18. パズルとゲーム

 ゲームとパズルのプログラムを取り上げます。どちらもコンピュータが問題を解いているように見えるかもしれませんが、解法はプログラムとして与えていることに注意してください。

18.1 石取りゲーム

 10個の石があります。交互に1~3個の石を取り、最後に石を取ったら負けというゲームです(奥村晴彦「C言語による最新アルゴリズム事典(技術評論社)」)。


 プログラムの戦略は以下の箇所にあります。相手が1個取ったらコンピュータは3個...というように4個ずつ確実に減らすことができるので、4の倍数+1個残せれば勝ちが決まります。それがだめなら1個取ります。

(練習) 石の数(N)や、取ることができる最大個数(M)を変え、コンピュータに勝つことができるかどうか試みなさい。

18.2 ハノイの塔

 3本の棒A,B,Cがあり、Aの棒にn枚(図では4枚)の円盤が積み重ねられています(図8)。これらの円盤をBの棒に移すにはどのような手順で移動したらよいでしょうか。ただし、円盤は1度に1枚ずつ移動し、小さな円盤の上に大きな円盤を重ねることはできません。

図8 ハノイの塔

 以下のプログラムは、どのように移動すればよいかを表示します。

 プロクラムはとても短いもので、関数 hanoi() の中では、hanoi() を再帰的に呼び出しています。from の n-1 枚の円盤をとりあえず buf に移し、次に from に残った1枚の円盤を to に移し、buf に移した n-1 枚の円盤を to に戻します。このように「より簡単な問題に分解して問題を解決する方法」を分割統治といいます。

 この例のように「自分の考え方が正しいかどうか」を実際にプログラムを作って検証するということはプログラミングの重要な利用法のひとつです。


19. 対話型学習ソフト

19.1 記述式クイズ

 以下の pair.awk は「対の関係」を記述式で問うプログラムです。データを変えれば、「日本語を示し、英単語を問う問題」、「英単語を示し、逆の意味の英単語を問う問題」、「漢字を示し、読みを問う問題」などとなります。

(練習) pair.awk のプログラムを変更し、全問終了後に正答数を表示するようにしなさい。

(練習) 7で取り上げたshuffle()を使い、出題順をランダムにしなさい。

19.2 穴埋め問題

(練習) pair.awkのプログラムを変更し、データファイルの構成を、「問題,解答1,解答2,...」のようにし、2つ以上の解答を許すようにしなさい。

(練習) 以下のように、各問複数の項目を問うプログラムを作りなさい。

(練習) 選択式のクイズプログラムを作りなさい。

19.3 CAIプログラム

 少し実用性を考慮したCAIプログラムを紹介します。問題ファイル(cai.csv)の内容は次のように扱われ、問題文を自由記述できます。

  1. 「A:」で始まる行は、$2を尋ねて答えを入力させ、正解($3)との一致を調べて表示する。

  2. 空行(改行だけの行)では「次の問題(Enterキー)」と表示してキー操作を促す。

  3. 上記以外の行はそのまま表示される。

 なお、多少拡張したプログラムが sample フォルダにあります。

で試すことができます。誤答の場合にヒントを出したり、全問回答後に回答記録を表示したり(実際はファイルに記録して後から分析する)、機能を拡張しています。


 誤答時にヒントを出すなど、いくつかのパターンのクイズを作成できるJavaScriptプログラムがこちらにあります。

(練習) データの構成を「問題,解答,ヒント」とし、誤答の場合はヒントを出すようなプログラムを考えなさい。

(練習) 誤答の場合は補足問題を解かせるようなプログラムを考えなさい。

(練習) 解答の正誤で次に出す問題の難易度を変えるようなプログラムを考えなさい。


koyama88@cameo.plala.or.jp