促音を通常の大きさに変換

codeなにがし::促音を通常の大きさに変換したいのですが、添削お願いしますのようなものを見ていると、awk に tr コマンドや sed の y コマンドのような演算子が欲しいと思うことが多々あります。 ただし、awk 自身で比較的簡単にこうした関数を記述することができますので、ここでは awk で tr() 関数を作ってみたいと思います。

文字単位で分割するには split() 関数の第 3 引数を空文字にすることで可能ですので、この機能を用います。 ただし、nawk や mawk は日本語のようなマルチバイトの分割はできませんので、ここでは gawk を用いることを前提にしています。

#! /usr/local/bin/gawk -f
# str_normalize.awk
# 促音を通常の大きさに変換
# gawk -f str_normalize.awk file(s)

{
    print _str_normalize($0);
}

# _str_normalize():     促音を普通の大きさに変換
#   in:     文字列 (str)
#   out:    置換された文字列 (str)
function _str_normalize(str) {
    str = tr("ァィゥェォッヵヶャュョヮ", "アイウエオツカケヤユヨワ", str);
    return str;
}

# tr():     tr や sed の y コマンドのような置換を行う
#   in:     置換前文字列 (before)
#           置換後文字列 (after)
#           置換対象文字列 (str)
#   out:    置換後文字列 (str)
function tr(before, after, str,
                num_before, num_after, arr_before, arr_after, i) {
    num_before = split(before, arr_before, "");
    num_after  = split(after,  arr_after,  "");

    if (num_before != num_after) {
        print "置換するべき数が違います" > "/dev/stderr";
        exit 1;
    }

    for (i = 1; i <= num_before; i++) {
        gsub(arr_before[i], arr_after[i], str);
    }

    return str;
}

実際に実行してみましょう。

$ echo 'トウキョウトッキョキョカキョクキョカキョクチョウ' | \
  gawk -f str_normalize.awk
トウキヨウトツキヨキヨカキヨクキヨカキヨクチヨウ

AWK Users JP :: ニコニコ大百科の言葉を PC に覚えさせる前準備では sed_y() 関数として同様の関数が出現していますが、Perl の CPAN のように全世界レベルで有用な関数をまとめてくれるところがないのが awk の欠点のひとつと言えるでしょう。 CPAN のようなものが整備でき、プラグマの形で容易に導入することができれば、もっと簡単に扱えるようになるかもしれません。

tag_gawk.pngtag_gawk.png