廿TT

譬如水怙牛過窓櫺 頭角四蹄都過了 因甚麼尾巴過不得

AWK で新しいことわざを作る

動機

カットアップで小説を書いたウィリアム・バロウズという作家をご存知だろうか。

カットアップとは印刷物の文章をハサミで切って並べ替え、おもしろそうなフレーズができたらそれをそのまま使うという手法だ。

実にお手軽。誰にでもまねできそうだ。

しかしペーパーレス化が求められる今の時代に、実際に印刷物をハサミで切るのはもったいない。

そこで我々は電子テキストを使う。

電子テキストを切り刻むのはかんたんだ、AWK さえあれば。

カットアップ対象と下処理

優秀なエンジニアの方なら形態素解析で文章を切り刻んでマルコフ連鎖でくっつけるとかするのかもしれないが、ぼくはあいにく優秀なエンジニアではないのでもっとお手軽にカットアップがしたい。

そこで単に助詞の「てにをは」で文をカットして一様乱数でくっつけることにする。

あまり複雑な文章だとこの手法は使えない。

今回カットアップ対象に選んだのは ことわざ一覧 である。

このページをコピペしてテキストエディタに貼り付けると、

【あ】
 01.会うは別れの始め
 02.青菜に塩
 03.青は藍より出でて藍よりも青し
...

というようなファイルができる。ファイル名は「ことわざ.txt」としよう。

【あ】とか01.とかの部分は邪魔なので取り除く。

コマンドラインで以下のようにタイプすればいい。

awk '/./{split($0,a,"."); print a[2]}' ことわざ.txt > kotowaza.txt

「.」を含む行だけ取り出して「.」の前後で文字列を分割し、後半部だけ print している。

kotowaza.txt というファイルができた(kotowaza.txt · GitHub)。

コーディング

カットアップを実行する AWK のコードは以下のようになった。

#kotowazamixer.awk
BEGIN{srand();
  joshi[1]="て";
  joshi[2]="に";
  joshi[3]="を";
  joshi[4]="は";
  joshi[5]="が";
  joshi[6]="ば";
  tmp = joshi[int(rand()*6)+1];
}
$0~tmp{
	split($0,a,tmp);
	x[i]=a[1];
	y[i]=a[2];
	i++;
}
END{
	for(j=1;j<=10;j++)
	print x[int(rand()*i)+1] tmp y[int(rand()*i)+1];
}

やっていることはこんな感じだ:

  1. srand() という関数で乱数の種を初期化する。
  2. 長さ 6 の配列 joshi に助詞「て」、「に」、「を」、「は」、「が」、「ば」を与える。
  3. joshi のなかから助詞を選び tmp とする。
  4. tmp を含む行だけ抽出。
  5. 文字列を助詞 tmp で区切って前半部と後半部にわける。
  6. ランダムに選んだ前半部と、ランダムに選んだ後半部を、助詞 tmp をはさんでくっつける。

実行結果

コマンドラインに以下のようにタイプするとことわざが生成される。

awk -f 'kotowazamixer.awk' kotowaza.txt

何回か実行した結果、生成されたことわざの一部を抜粋する。

  • 一寸先は蛙
  • 据膳食わぬは三文の徳
  • 短気は百薬の長
  • 爪に手を噛まれる
  • 木に似たり
  • 多勢に逆らう
  • 石に茄子は生らぬ
  • 石には勝てぬ
  • 大欲は本能寺にあり
  • 芸術は友を呼ぶ
  • 悪貨は良貨を噛み潰す
  • 味噌を笑う
  • 噂をすれば水心
  • 塵も積もれば熱さを忘れる
  • 鬼の目に金棒
  • 木に竹を付ける
  • 鬼が笑う
  • 金の切れ目が葱を背負って来る
  • 腐って穴を掘る
  • 仏作って蛇を出す

個人的お気に入りは「石に茄子は生らぬ」の当たり前な感じとか、「芸術は友を呼ぶ」のなんか深そうな感じとかである。「多勢に逆らう」の生意気さもよい。

参考文献

たかがバロウズ本。

たかがバロウズ本。

プログラミング言語AWK

プログラミング言語AWK

  • 作者: A.V.エイホ,P.J.ワインバーガー,B.W.カーニハン,足立高徳
  • 出版社/メーカー: USP研究所
  • 発売日: 2010/01/01
  • メディア: 単行本(ソフトカバー)
  • クリック: 1回
  • この商品を含むブログを見る

ソフトマシーン (河出文庫)

ソフトマシーン (河出文庫)

AWK Users JP :: サイコロを 100 回振って各目の出る割り合いを求める

動的正規表現を使って任意の変数と文字列をマッチさせる - もっと早く知っていれば良かった