日本語ファイル名のファイルを探し出せ

日本語のファイル名というのは Unix 系 OS ではご法度とされていた時代もありましたが、今や Linux では積極的に用いても問題が起きることも珍しくなってきました。 日本語ファイル名のファイルを探し出せでは「asciiだけなら終了コード0で終了するコマンド」となっていますが、ここでは ascii だけかどうかを判断する is_ascii() 関数を作ってみます。

ご存知のように awk には日本語のようなマルチバイトを区別するための手段がありません。 ある友人から教わった「EUC-JP でも UTF-8 でも文字列に変化がなければ ascii である」ということを利用して、さらに nkf を用いています。 awk は単独で全てをこなすのではなく、Unix 系 OS の便利なコマンドと組み合わせることで様々な処理を行えるようになります。

#! /usr/bin/gawk -f
# ascii_only.awk
# http://d.hatena.ne.jp/mzp/20090219/nihongo

!is_ascii($0)

# is_ascii():   文字列 str が ASCII かどうかを判定する
#   in:     文字列 str
#   out:    0 … ASCII 以外を含む
#           1 … ASCII のみである
function is_ascii(str) {

    # nkf で異なる文字コードに変換しても変わらないものが ASCII であると
    # 仮定する
    com_utf8 = "echo '" str "' | nkf -w";
    com_euc  = "echo '" str "' | nkf -e";
    com_utf8 | getline utf8_str;
    close(com_utf8);
    com_euc  | getline euc_str;
    close(com_euc);

    if (utf8_str == euc_str) {
        return 1;
    } else {
        return 0;
    }
}

実行してみましょう。

$ echo 'あいうえお' | nawk -f ascii_only.awk
あいうえお
$ echo 'aiueo' | nawk -f ascii_only.awk

このように利用することができます。

gawk の場合には close() でパイプを閉じなくても問題ありませんが、nawk などで実行する場合はパイプを閉じてください。 そうしないと find の出力結果などを渡すとパイプの開き過ぎで止まってしまいます。

$ find ~ | nawk -f ascii_only.awk
/home/hi_saito/Podcasts/英会話 eChat Vancouver
<snip>

tag_nawk.pngtag_nawk.pngtag_nawk.pngtag_nawk.png