iPhone 5の軽さに慣れたタイミングで我が家にやってきた「iPad mini」。いやあ、ラクです。とにかく軽い。iPad用に最適化されたデジタルマガジンを見る場合、ちょっと文字が小さいかな、と感じることはありますが、なにせ軽いので許せてしまいます。今後は取材のときにも活躍しそうです。
さて、今回は「日本語ロケール」について。ふだん何気なく利用していると気付かないが、OS Xにはいくつかのロケール機構が存在する。そのしくみを解説するとともに、ロケール機構により日本語メッセージを出力するコマンド「date」の使い方を紹介してみよう。
OS Xのロケールのしくみ
多言語対応のソフトウェアは、出力するメッセージの内容や通貨・日付などの単位を国/地域によって切り替える機構を備えている。それが「ロケール」で、多言語対応のOSであるOS Xにおいても、ロケール機構により日本語や英語、フランス語といった各種言語を切り替えている。
その設定ツールが、システム環境設定の「言語とテキスト」パネルだ。そこに表示されている言語のリストは、システムおよびアプリケーションから参照され、もっとも上に表示されているものが最優先でロケールとして適用される。だからOS Xを日本語環境で利用している場合、いちばん上の行には「日本語」と表示されているはずだ。
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
このロケール関連の環境変数に影響を受けるコマンドで好例が「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"です" `