iPhone 5の軽さに慣れたタイミングで我が家にやってきた「iPad mini」。いやあ、ラクです。とにかく軽い。iPad用に最適化されたデジタルマガジンを見る場合、ちょっと文字が小さいかな、と感じることはありますが、なにせ軽いので許せてしまいます。今後は取材のときにも活躍しそうです。

さて、今回は「日本語ロケール」について。ふだん何気なく利用していると気付かないが、OS Xにはいくつかのロケール機構が存在する。そのしくみを解説するとともに、ロケール機構により日本語メッセージを出力するコマンド「date」の使い方を紹介してみよう。

OS Xのロケールのしくみ

多言語対応のソフトウェアは、出力するメッセージの内容や通貨・日付などの単位を国/地域によって切り替える機構を備えている。それが「ロケール」で、多言語対応のOSであるOS Xにおいても、ロケール機構により日本語や英語、フランス語といった各種言語を切り替えている。

その設定ツールが、システム環境設定の「言語とテキスト」パネルだ。そこに表示されている言語のリストは、システムおよびアプリケーションから参照され、もっとも上に表示されているものが最優先でロケールとして適用される。だからOS Xを日本語環境で利用している場合、いちばん上の行には「日本語」と表示されているはずだ。

システム環境設定「言語とテキスト」パネル。ここで最優先に設定した言語が「.CFUserTextEncoding」に記録される

2行目以降は、最優先の言語に対応したリソースがシステム/アプリケーションに存在しない場合適用される。たとえば、日本語の言語リソースを持たないアプリケーションを起動した場合は、2行目の言語リソースの有無を試し、それもなければ3行目……という順序で処理される。

その「言語とテキスト」パネルで設定した最優先言語の情報は、ホームフォルダに「.CFUserTextEncoding」というファイル名で記録される。先頭が「.」から始まるFinderでは不可視のファイルだが、Terminalでcatコマンドなどを使い内容を表示すれば、日本語が最優先のときは「1:14」、英語は「0:00」、ドイツ語は「0:30」……と値が変わることを確認できるはずだ。

シェルの世界のロケールは?

と、ここまではOS X独自のレイヤーでの話。シェルとその上で動作する各種コマンドは、決められた環境変数を参照して使用する言語を決定する。日付と時刻のフォーマットを設定する「LC_TIME」、通貨単位や金額の表記を決める「LC_MONETARY」などいくつかの種類があるが、これらをまとめて設定するために「LC_ALL」と「LANG」が用意されている。

なお、「LC_ALL」は他のロケール用環境変数に優先され、どのような値が設定されていても上書きする。一方の「LANG」はもっとも効果が弱く、他のロケール用環境変数に上書きされてしまう。もっとも、多くのコマンドは「LANG」を設定しておけばじゅうぶんで、日本語環境(テキストエンコーディングはUTF-8)で利用する場合は、以下のような記述をシェルのスタートアップファイル(「~/.bashrc」や「~/.bash_profile」など)へくわえておけばいい。

export LANG=ja_JP.UTF-8

Terminalでlocaleコマンドを実行し、現在のロケール用環境変数を一覧したところ

このロケール関連の環境変数に影響を受けるコマンドで好例が「date」コマンドだ。OS Xに収録されているdateコマンドは多言語対応で、指定されたロケールで月日の表示スタイルを変更する。たとえば、以下のとおりコマンドを実行すると、上から順に米国(en_US.UTF-8)、日本(ja_JP.UTF-8)、中国語繁体字(zh_TW.UTF-8)のスタイルで現在時刻を表示できる。

$ LC_TIME=en_US.UTF-8 date
Mon Nov 12 20:14:03 JST 2012

$ LC_TIME=ja_JP.UTF-8 date
2012年 11月12日 月曜日 20時14分23秒 JST

$ LC_TIME=zh_TW.UTF-8 date
2012年11月12日 周一 20時14分57秒 JST

dateコマンドとKyokoさんは好相性?

さて、Terminalにおけるロケールの仕組みを一通り説明したところで、次はdateコマンドを活用してみよう。その対象は……「say」コマンド。そう、流ちょうな日本語を話すKyokoさん(名前からして当然だが)にdateコマンドの出力を渡せば、なかなか実用的なことができるのだ。第38回でsayコマンドを取り上げたときの応用編、と考えていただいて差し支えない。

まず、表1をご覧いただきたい。dateコマンドでは、システムが持つ日時情報をさまざまなフォーマットで出力できるが、そのうちいくつかがロケール対応となっている。日本語ロケールを設定していれば、現在時刻を「20時30分25秒」のように時分秒の単位付きで返してくれたり、曜日を「月曜日」や「火曜日」などとしてくれたりするのだ。

表1:dateコマンドで使えるロケール対応のフォーマット

フォーマット 内容 出力例
%A 曜日 月曜日、火曜日
%B 11月、12月
%a 曜日 月、火、水
%X 時分秒 20時49分03秒

これを多少加工してsayコマンドに引き渡せば、なかなかイイ感じでKyokoさんが話してくれる。手はじめは、現在時刻。現在時刻情報の前に「ただいま」、末尾に「です」をくわえて出力することで、sayコマンドには「ただいま20時55分05秒です」という文字列が引き渡され、その結果Kyokoさんも自然な感じで現在時刻を読み上げてくれる。

$ date +"ただいま"%X"です" | say

または

$ say `date +"ただいま"%X"です"`

次に紹介する事例は、コマンド実行時点の月日に続けて曜日を読み上げるというもの。たとえば、11月12日に実行すると、「きょうは11月12日、月曜日です」という声が聞こえる。Terminalの起動直後に実行するよう設定しておくなど、なかなか実用的なのではないだろうか。本当は、launchdを使いsayコマンドを自動実行するところまで解説するつもりだったのだが、紙幅が尽きてしまい……それはまたの機会とさせていただきたい。

$ date +"きょうは"%B%e"日、"%A"です" | say

または

$ say `date +"きょうは"%B%e"日、"%A"です" `