2011年7月15日金曜日

GNU libc UTF-8文字幅

最近は linux でもファイル名やディレクトリ名に日本語を使うことも多くなってきているようです。個人的にはファイル名にASCII文字以外を使用したくはないのですが、添附メールでもらったりとか、MS-Windows や Macintosh のファイル共有など色々と必要となる場面があります。

このような日本語の文字や記号をファイル名に使用している場合 ls などの表示桁がズレてしまうという経験をしている人も多いのではないかと思います。

これは UTF-8ロケール等で ls の認識している文字幅と、端末が認識している文字幅が異っていることが原因です。端末の文字幅設定の変更方法はそれぞれご存知かと思いますが、ls などの一般コマンド使用する文字幅が変更できることはあまり知られていないようです。

ls などの一般コマンドは libc のロケール機能を使って文字幅を決定しています。linux ならば GNU libc ということになります。この libc の文字幅は localedef コマンドを使用して定義することができます。標準の定義ファイルが /usr/share/i18n/charmap/UTF-8 にあるので、このファイルをコピーして編集して、localedef コマンドに与えることにより文字幅を変更できます。

以下サンプルとして、私の使用している文字定義ファイルを置いておきますのでダウンロードして試してみてください。

ダウンロード: glibc-UTF-8-width.tar.gz

使い方等は「もっと読むで」で



中に三つのファイルがあり、それぞれ以下のような文字幅定義になっています。
UTF-8-N
Unicode の標準文字幅です。GNU libc に付属の UTF-8 とほぼ同じですが、Unicode-6.0.0規格にアップデートしてあります。
UTF-8-CJK
Unicode の CJK 文字幅になります。
UTF-8-JA
日本語の互換文字幅です。Uhicode の CJK文字幅に加えて JIS X 0212/0213 の文字全てを全角扱いします。

例えば LANG=ja_JP.utf8 の時の文字幅を、日本語互換文字幅にしたい場合には root 権限で以下のコマンドを実行します。
localedef -f ./UTF-8-JA -i ja_JP ja_JP.utf8
これにより ja_JP.utf8 の文字幅が UTF-8-JA で指定してあるものに変更されます。
この定義はロケールごとに設定が可能なので en_US.utf8 の時には Unicode の標準文字幅を、zh_CN の時は CJK文字幅を、ja_JP.utf8 の時には日本語互換文字幅を設定するようなことも可能です。
localedef -f ./UTF-8-N -i en_US en_US.utf8
localedef -f ./UTF-8-CJK -i zh_CN zh_CN.utf8
localedef -f ./UTF-8-JA -i ja_JP ja_JP.utf8
root 権限を持っていない場合や、何らかの理由でシステム全体の設定は変更せずに個人環境で一時的に文字幅の設定を変更したい場合には LOC_PATH 環境変数が使用できます。例えば $HOME/loclae/ja_JP.utf8 以下に日本語互換文字幅の定義を置きたい場合には以下のようにして作成します。
mkdir $HOME/loclae
loclaedef -f ./UTF-8-JA -i ja_JP $HOME/locale/ja_JP.utf8
その上で、例えば以下の環境変数を設定をすれば文字幅の定義が使用できます。
LOC_PATH=$HOME/locale:/usr/share/locale
export LOC_PATH
LANG=ja_JP.utf8
export LANG
いろいろ試してみてください。

0 件のコメント:

コメントを投稿