IT pass HikiWiki - [Exp2011]文字コードあれこれ Diff

  • Added parts are displayed like this.
  • Deleted parts are displayed like this.

[
((<"2011 スケジュール表・各回資料(06/24)"|[Exp2011]スケジュール表・各回資料#06-2F24>))
]

実習:
[
((<"実習事前準備"|"[Exp2011]06/24実習事前準備">))
|
((<"最低限リモートアクセス"|[Exp2011]最低限リモートアクセス>))
|
((<"最低限セキュリティ対策"|[Exp2011]最低限セキュリティ対策>))
|
((<"公開鍵認証を使ったssh接続実習"|[Exp2011]公開鍵認証を使ったssh接続実習>))
|
文字コードあれこれ
]

<目次>
{{toc_here}}

= ◎文字コードあれこれ

この実習を行う際は, レクチャー資料 ((<"Network Computing & Internet Security"|URL:/~itpass/exp/fy2011/110624/lecture/pub/>)) の Page37〜も参考にして下さい.

ここでは
EUC-JP, ShiftJIS, Unicode(UTF-8) で記述されたファイルを使用して

* 文字コードを指定してファイルを表示する.
* 文字コードを変換する

なんて事をしてみます.

== ファイルを表示する.

ファイルを適切に表示するためにはファイルの文字コードに合わせて,

(1) 端末で表示する文字コード
(2) シェルの環境変数(LC_*, LANG)

をきちんと設定する必要があります
((-
"((<lv|URL:http://www.ff.iij4u.or.jp/~nrt/lv/>))"
などの高機能なプログラムを使用すると
端末の環境変数やファイルの文字コードを自動判別して,
適切に処理してくれたりします.
ですが自動判別に失敗した場合や,
これらの高機能ページャを使用できない場合には
やはり設定が必要です.-)).

=== 端末で表示する文字コード

「表示にどの文字コードを使用するか」の設定は使用するターミナル
によって異なります.
今回の実習で使用する
gnome-terminal と mlterm について言語の切り替え方は以下の通りです.

* gnome-terminal の場合
  * 上のメニュー内の「端末(T)」をクリック
  * 「文字コードの設定」より, 使用したい文字コードを選択

((<URL:/~itpass/exp/fy2011/110624/practice/hiki-images/gnome-terminal-select-locale.png>))

* mlterm の場合
  * ターミナル上で Ctrl キーを押しながら右クリック
  * 出てきたメニュー内の「エンコーディング」で文字コードを選択

((<URL:/~itpass/exp/fy2011/110624/practice/hiki-images/mlterm-select-locale.png>))

その他のターミナルの場合については詳しくは触れません.
それぞれのマニュアルを参照して下さい.

=== 環境変数の確認・設定

多くのソフトウェアやプログラミング言語は,
使用する文字コードとともに,
国毎に異なる「((*単位, 記号, 日付, 通貨などの表記規則*))」を設定することで,
データの表記を(場合によっては処理まで)行ないます.
この表記規則のことを((*ロケール(locale)*)) と言います.

ロケールの切りかえは, 以下に示した環境変数で行ないます.
環境変数そのものについては 05/13 の実習「((<"シェル--環境変数"|[Exp2011]シェル#B4-C4-B6-AD-CA-D1-BF-F4>))」を参照して下さい.

: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

となっています((-こう書くと「LANGUAGE を設定しておけば良いんだ」と考える人もいるかもしれませんが, LANGAUGE は GNU gettext を使用する一部のプログラムでしか使用されません-)).
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 の略((- かつて通産省肝いりで進められていたΣプロジェクトで, EUC-JP を UJIS と読んでいた事に起因する呼び名.-))で, 結局の所 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

です.

では, 試しに, 故意に間違った表示をさせてみましょう.

:実習その4:環境変数 LANG と端末の表示に使う文字コードを別の種類に変えて, "man man" の結果を故意に文字化けさせてみて下さい.

確認したら, 元に戻しておきましょう - -;)

=== ファイルの表示

ここの実習に使用する以下のファイルを
手元の情報実験機にダウンロードしておいて下さい.

  * ((<text_sjis.txt|URL:/~itpass/exp/fy2011/110624/practice/text_sjis.txt>))
  * ((<text_eucjp.txt|URL:/~itpass/exp/fy2011/110624/practice/text_eucjp.txt>))
  * ((<text_utf8.txt|URL:/~itpass/exp/fy2011/110624/practice/text_utf8.txt>))

ダウンロードには wget というコマンドを用います.

  $ wget http://itpass.scitec.kobe-u.ac.jp/~itpass/exp/fy2011/110624/practice/text_sjis.txt
  $ wget http://itpass.scitec.kobe-u.ac.jp/~itpass/exp/fy2011/110624/practice/text_eucjp.txt
  $ wget http://itpass.scitec.kobe-u.ac.jp/~itpass/exp/fy2011/110624/practice/text_utf8.txt

これらのファイルをそれぞれ端末に表示させてみます. ここでは less や lv
といった(高機能な)ページャを使用せず, cat コマンドでファイルの中身を端
末に表示させてみましょう.

$ cat text_sjis.txt
$ cat text_eucjp.txt
$ cat text_utf8.txt

どれか一つはそれなりに表示される筈ですが, 残り二つは悲しい結果になると思います.
ちなみに表示が崩れてしまった場合には "reset" コマンドで端末表示をリセットしてみて下さい.

:実習その5:環境変数 LANG もしくは端末の表示に使う文字コードを切り替えることで, 上記三つのファイルをそれぞれ適切に表示して下さい.

...できましたか?

== 文字コードの変換

「linux で作成したファイルを Windows で見ると文字化けがおきてしまう」と
いった事は良くあります. 単なるテキストもさることながら, 苦心して作成し
たプログラムや, 頑張って書いた論文などが文字化けの為に解読できない, と
いうのは困りますよね?

ここでは, 文字コードの変換を行なってみましょう. UNIX 系の計算機における
代表的な文字コード変換プログラムには,

* ((<nkf|URL:http://sourceforge.jp/projects/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 [変換するテキストファイル]

となります. それでは最後の実習です.

:実習その6:先程ダウンロードしたファイルの文字コードを判別し, 結果が正しくなるかを確認して下さい. また, text-eucjp.txt の中身を Shift_JIS に, text-utf8.txt の中身を junet コードに, text-sjis.txt の中身を UTF-8 に変換して下さい. 変換方法はお任せします.

以上で実習は終了です. お疲れ様でした.



前項: [
((<"公開鍵認証を使ったssh接続実習"|[Exp2011]公開鍵認証を使ったssh接続実習>))
]

[
((<"2011 スケジュール表・各回資料(06/24)"|[Exp2011]スケジュール表・各回資料#06-2F24>))
]