[Exp2012]文字コードあれこれ
◎文字コードあれこれ
この実習を行う際は, レクチャー資料 Network Computing & Internet Security の Page37〜も参考にして下さい.
ここでは EUC-JP, ShiftJIS, Unicode(UTF-8) で記述されたファイルを使用して
- 文字コードを指定してファイルを表示する.
- 文字コードを変換する
なんて事をしてみます.
ファイルを表示する.
ファイルを適切に表示するためにはファイルの文字コードに合わせて,
- 端末で表示する文字コード
- シェルの環境変数(LC_*, LANG)
をきちんと設定する必要があります *1.
端末で表示する文字コード
「表示にどの文字コードを使用するか」の設定は使用するターミナル によって異なります. 今回の実習で使用する gnome-terminal と mlterm について言語の切り替え方は以下の通りです.
- gnome-terminal の場合
- 上のメニュー内の「端末(T)」をクリック
- 「文字コードの設定」より, 使用したい文字コードを選択
- mlterm の場合
- ターミナル上で Ctrl キーを押しながら右クリック
- 出てきたメニュー内の「エンコーディング」で文字コードを選択
その他のターミナルの場合については詳しくは触れません. それぞれのマニュアルを参照して下さい.
環境変数の確認・設定
多くのソフトウェアやプログラミング言語は, 使用する文字コードとともに, 国毎に異なる「単位, 記号, 日付, 通貨などの表記規則」を設定することで, データの表記を(場合によっては処理まで)行ないます. この表記規則のことをロケール(locale) と言います.
ロケールの切りかえは, 以下に示した環境変数で行ないます. 環境変数そのものについては 06/01 の実習「シェル--環境変数」を参照して下さい.
- ["LC_CTYPE"]
- 文字の種類とエンコーディングの指定
- ["LC_COLLATE"]
- ソートのルールの指定
- ["LC_TIME"]
- 日付の書式の指定
- ["LC_NUMERIC"]
- 数字の書式の指定
- ["LC_MONETARY"]
- 通貨の書式の指定
- ["LC_MESSAGES"]
- メッセージ表示に使用する言語の指定
- ["LC_PAPER"]
- 紙のサイズ
- ["LC_NAME"]
- 名前のフォーマット
- ["LC_ADDRESS"]
- 住所のフォーマット
- ["LC_TELEPHONE"]
- 電話番号のフォーマット
- ["LC_MEASUREMENT"]
- 長さの単位
- ["LC_IDENTIFICATION"]
- これらの変数用のメタデータ.
- ["LC_ALL"]
- 上記 LC_CTYPE…LC_TIME を全て上書き(他の指定より, LC_ALL の設定を優先)します.
- ["LANGUAGE"]
- LC_MESSAGES の設定を上書きします. GNU gettext だけ(?)が使用します. よって GNU gettext を内部で使用している全てのプログラムでは, LANGUAGE が使用されます.
- ["LANG"]
- 全ての LC_* 変数のデフォルト. LC_* が指定されていない場合には LANG の値が適用されます.
- ["LOC_PATH"]
- 言語のデータの置き場. 通常は /usr/share/locale に置かれる.
これらの変数の優先順位は
LANGUAGE > LC_ALL > LC_* > LANG
となっています*2. LC_* をひとつづつ設定するのは面倒ですので, 通常は LC_ALL もしくは LANG を設定します. ここでは LANG を設定してみましょう.
先ず 現在の言語設定を確認してみましょう. locale コマンドを引数無しで実行してみて下さい.
$ locale LANG=ja_JP.UTF-8 LC_CTYPE="ja_JP.UTF-8" LC_NUMERIC="ja_JP.UTF-8" LC_TIME="ja_JP.UTF-8" LC_COLLATE="ja_JP.UTF-8" LC_MONETARY="ja_JP.UTF-8" LC_MESSAGES="ja_JP.UTF-8" LC_PAPER="ja_JP.UTF-8" LC_NAME="ja_JP.UTF-8" LC_ADDRESS="ja_JP.UTF-8" LC_TELEPHONE="ja_JP.UTF-8" LC_MEASUREMENT="ja_JP.UTF-8" LC_IDENTIFICATION="ja_JP.UTF-8" LC_ALL=
などと表示されたと思います(環境によって結果は異なると思います). 上記の結果は "LANG" が "ja_JP.eucJP", LC_ALL が空白ですから, "LANG"" のみが設定されており, LC_* は全て LANG の値が用いられたのだと想像されます.
続いて システムでサポートされている言語を確認してみます. 以下のコマンドを実行してみて下さい.
$ locale -a C POSIX ja_JP ja_JP.eucjp ja_JP.ujis ja_JP.utf8 japanese japanese.euc :
ujis は UNIX JIS の略*3で, 結局の所 EUC-JP を指します. よって, このシステムでは
- EUC-JP: ja_JP.eucjp
- UTF-8: ja_JP.utf8
がサポートされていることがわかります.
それぞれの文字コードを使用する際に環境変数 LANG に何を指定すれば良いかは, システムに依存しています. Debian の場合は,
- EUC-JP
- ja_JP.EUC-JP
- ja_JP.eucJP
- ja_JP.ujis
- ja_JP.eucjp
- UTF-8
- ja_JP.UTF-8
- ja_JP.utf8
です.
では, 試しに, 故意に間違った表示をさせてみましょう.
確認したら, 元に戻しておきましょう - -;)
ファイルの表示
ここの実習に使用する以下のファイルを 手元の情報実験機にダウンロードしておいて下さい.
ダウンロードには wget というコマンドを用います.
$ wget http://itpass.scitec.kobe-u.ac.jp/~itpass/exp/fy2012/120601/practice/text_sjis.txt $ wget http://itpass.scitec.kobe-u.ac.jp/~itpass/exp/fy2012/120601/practice/text_eucjp.txt $ wget http://itpass.scitec.kobe-u.ac.jp/~itpass/exp/fy2012/120601/practice/text_utf8.txt
これらのファイルをそれぞれ端末に表示させてみます. ここでは less や lv といった(高機能な)ページャを使用せず, cat コマンドでファイルの中身を端 末に表示させてみましょう.
$ cat text_sjis.txt $ cat text_eucjp.txt $ cat text_utf8.txt
どれか一つはそれなりに表示される筈ですが, 残り二つは悲しい結果になると思います. ちなみに表示が崩れてしまった場合には "reset" コマンドで端末表示をリセットしてみて下さい.
...できましたか?
文字コードの変換
「linux で作成したファイルを Windows で見ると文字化けがおきてしまう」と いった事は良くあります. 単なるテキストもさることながら, 苦心して作成し たプログラムや, 頑張って書いた論文などが文字化けの為に解読できない, と いうのは困りますよね?
ここでは, 文字コードの変換を行なってみましょう. UNIX 系の計算機における 代表的な文字コード変換プログラムには,
- nkf
- iconv (GNU の C ライブラリに含まれるプログラム)
などがあります. ここでは nkf を使って文字コードを変換してみます.
nkf (Network Kanji Filter)
nkf については, 以下の man からの引用を参照して下さい.
nkf はネットワークでメールやニュースの読み書きをするために作られた、漢 字コードの変換フィルタである. この nkf の特徴としては、入力漢字コード系の統計的な自動認識機能がある. このため、利用者は、入力漢字コード系が何であるかを知らなくても、出力漢 字コード系のみ指定すれば良いことになる. ただ、この判定機構は、理論的に は完全ではないが、通常のニュースやメールのメッセージについては確実に動 作する安全なものにはなっている.
良く使う引数は以下の通りです.
- ["-j"]
- junet コードを出力する. (デフォルト)
- ["-e"]
- EUC コードを出力する.
- ["-s"]
- Shift_JIS コードを出力する.
- ["-w"]
- Unicode を出力する.
- ["-J"]
- 入力として junet コードを仮定する.
- ["-E"]
- 入力として EUC コードを仮定する.
- ["-S"]
- 入力として Shift_JIS コードを仮定する.
- ["-W"]
- 入力として Unicode を仮定する.
- ["-g"]
- 自動判別の結果を出力する.
- ["--overwrite もしくは --in-place"]
- 変換結果で元のファイルを上書きする.
例えば, 文字コードを自動判別させる場合には以下の様にコマンドを実行します.
$ nkf -g [判別させるテキストファイル]
次の様にコマンドを実行すると, 変換した結果を端末(標準出力)へ表示します. 以下の例では junet コードのファイルを EUC-JP へ変換し, 端末へ表示します.
$ nkf -Je [変換するテキストファイル]
変換結果を保存するには以下の二通りの方法があります.
リダイレクトを用いる場合には
$ nkf -Je [変換するテキストファイル] > [変換後ファイル名]
上書き保存する場合する場合には
$ nkf -Je --overwrite [変換するテキストファイル]
となります. それでは最後の実習です.
以上で実習は終了です. お疲れ様でした.
*1
"lv"
などの高機能なプログラムを使用すると
端末の環境変数やファイルの文字コードを自動判別して,
適切に処理してくれたりします.
ですが自動判別に失敗した場合や,
これらの高機能ページャを使用できない場合には
やはり設定が必要です.
*2こう書くと「LANGUAGE を設定しておけば良いんだ」と考える人もいるかもしれませんが, LANGAUGE は GNU gettext を使用する一部のプログラムでしか使用されません
*3 かつて通産省肝いりで進められていたΣプロジェクトで, EUC-JP を UJIS と読んでいた事に起因する呼び名.
Keyword(s):
References:[[Exp2012]スケジュール表・各回資料]