メモ

覚書です

UTF-8のBOMとシェルスクリプト、エディタ、Vimなどの話題

2008-11-21 22:20:30 | Linux
UTF-8のBOMとシェルスクリプト、エディタ、Vimなどの話題

シェルスクリプトの一行目でエラーが出るなぁと思ったら、UTF-8のファイルの先頭に「EF BB BF」とかついていた。
colinuxのコンソールでcatすると「怯ィ」(ィは半角)とか頭に表示される。Puttyでは特に表示されないなぁ。
od -t x1でも確認できますね。
BOM(Byte Order Mark) とか呼ばれているもののようです。
Windowsのエディタで作成してUTF-8で保存したものを持ってきたからのようです。

これの削除でちょっとつまづきました。
ネットで調べつつ、これでいけるかなと思ったら、、、。
nkf -W8 -w80 test > test_nobom
iconv -c -f UTF-8 -t UTF-8 test > test_nobom

無理でした。バージョンによるのかなぁ。(nkf 2.0.7、iconv 2.7)

ちなみに
echo "test" > test1
nkf -W80 -w8 test1 > test2
nkf -W8 -w80 test2 > test3
diff test1 test3
test1とtest3が異なります。test2とtest3が同じ状態。BOMが消えませんでした。

nkf --ic=UTF-8-BOM --oc=UTF-8-BOM test1 | nkf --ic=UTF-8-BOM --oc=UTF-8-BOM | nkf --ic=UTF-8-BOM --oc=UTF-8-BOM
nkf -W8 -w8 test1 | nkf -W8 -w8 | nkf -W8 -w8
とかするとBOM?がどんどん増えます^^;

別の文字コード(UTF-16とかUTF-8以外)にいったん変換したら、消えてくれました。

nkf -w8 test1 | nkf -w
だとBOMつきだけど

nkf -w8 test1 | nkf -W8 -w16 | nkf -W16 -w
nkf -w8 test1 | nkf -w8 --oc=UTF-16BE | nkf --ic=UTF-16BE -w
だとBOMなしUTF-8に。

ただ
nkf -w8 test1 | nkf -w8 --oc=UTF-16 | nkf --ic=UTF-16 -w
nkf -w8 test1 | nkf -w8 --oc=UTF-16BE-BOM | nkf --ic=UTF-16BE-BOM -w
だとBOMつきとなりました。
マニュアルによるとUTF-16とUTF-16BEは同じとなっていたんだけどどうやら違うようだ。

ちなみにiconvではutf-16にいったん変換してutf-8に戻しても消えませんでした。
iconv -f utf-8 -t utf-16 test2 | iconv -f utf-16 -t utf-8
「EF BB BF」は「FF FE」として変換されます。それがutf-8に戻すと「EF BB BF」として変換されるみたいです。
utf-16の状態だとBOMの「FF FE」に加え変換された「FF FE」が続きます。
iconv -f utf-8 -t utf-16BE test2 | iconv -f utf-16 -t utf-8
iconv -f utf-8 -t utf-16LE test2 | iconv -f utf-16 -t utf-8
などとすればBOMが消えましたが問題が起きないか不安。
nkfもUTF-16BEに変換したらBOMなしで、UTF-16BE-BOMにしたらBOMつきになったけど、それとも違うよなぁ。
一応SJISやEUCJPに変換して戻せば消えます。また元々BOMがないutf-8をutf-16にいったん変換してutf-8に戻してもBOMはつきませんでした。

#ともかくもBOMはややこしいっていう印象^^;


BOMはWindowsのエディタによってつけるものとつけないものがあるみたいです。
XPのnotepadはつけるみたい。
エディタによってはつける、つけないを選べるものもあるみたい。
採用されなかった?けど、UTF-8Nという表記もあってその形式で保存できたりするものも。


vim(7.1)の場合、
:set nobomb
として保存すればBOMを取り除いてくれました。

BOMつきのUTF-8と確定している場合なら
tail -c +4 file > file_nobom
としてもいいかも。

ちなみに .vimrc を次のように書いてみたら、
:set termencoding=utf-8
:set fileencodings=iso-2002-jp,utf-8,euc-jp,cp932
なぜかBOMが画面に表示された。<feff>とか青い字で表示されます。
この場合:set bomb?はnobombとなります。

ためしに空ファイルをvimで作成。:set bombとして保存してみる。
開きなおすと<feff>が表示された。<feff>は一文字で削除すればBOMはなくなるみたい。

どうも
:set fileencodings=iso-2022-jp,utf-8,euc-jp,cp932
が問題みたい。
<feff>について、ちょっと調べてみる。ZERO WIDTH NO-BREAK SPACEと認識されてるのかな?
Wikipediaによると
ノーブレークスペース - Wikipedia
「ゼロ幅のノーブレークスペース。Unicodeでの名称は "ZERO WIDTH NO-BREAK SPACE" (U+FEFF)。この文字はUCS BOM (バイトオーダーマーク) としても使われることに注意。この多重定義のため、」云々。


.vimrcにfileencodingsを書かないと、普通に扱えている感じなので標準で何が設定されているか確認してみる。
:set fileencodings?
fileencodings=ucs-bom,utf-8,default,latin1
となっていた。これを参考にして、
:set fileencodings=iso-2022-jp,ucs-bom,utf-8,euc-jp,cp932,default,latin1
とすると、うまく扱えるようになりました。

参考サイト
Vimのメモ
UTF-8 ドキュメントの BOM を削除する
UTF-8N - odz buffer
某日記(中期) - UTF-8N の亡霊
第38回 XML勧告を記述するXMLspecとは何か

エディタが紹介されているサイト
PARALYSIS / UTF-8
フリーエディタ17選! <- クールなツール


#追記
BOM付UTF-8をUTF-8Yと表記することもあるらしい。

#エディタの評価結果
ブラウザ(FireFox3,IE7,Opera9)で表示できた文字がエディタで表示できるか試してみました。
正式な呼び方はわかりませんが、古代イタリック、ギリシャ拡張文字などを表示させてみました。
そのうちFireFox3では表示できましたが、「𪊲」がIE7、Opera9.62では表示できませんでした。
(何度もフォントを入れ替えたりしてたので、キャッシュが変になってた可能性もありますが。)
ちなみに「𪊲」はXPの場合、メイリオ フォントを導入すればFireFox3やNotepadで表示できます。Vistaでは標準で入っているらしいです。

●Notepad
フォントを用意すれば多言語混在で結構いけそうです。
BOMが必ずつくようです。

BabelPad Beta [2008-07-09]
BOMの有無を選択できます。
それぞれの領域について、どのフォントを適用するか選べるようです。
初回起動時に自動で一番字数が多いフォントを割り当ててくれるみたい。
同じ領域を扱うフォントによって、持っている字が異なると、割り当てたフォントによって表示できる字が決まってきます。
流石に他のフォントの字までは追跡してくれません。
(NotePadも似た感じ。)

Meadow 3.00 (KIKU) -- 開発版
多分BOMの有無を変更できると思う。ちゃんと調べてません。
「𪊲」、古代イタリックが表示できませんでした。
mule-fonts16を使うとギリシャ文字は表示できました。
表示できなかったものもフォントの設定でなんとかなるかも。
使いこなすのに、ちょっと時間がかかりそうな印象。

xyzzy version 0.2.2.235
BOMの有無を選択できます。(BOMなし=UTF-8Nで保存)
「𪊲」、古代イタリック、ギリシャ文字拡張などが表示できませんでした。
日本語情報が豊富なので、自分好みにカスタマイズしやすそう。
プロポーショナルフォントは利用できないみたい。

サクラエディタW 1.6.20
BOMの有無を選択できます。
一つだけフォントを設定できます。そのフォントに登録がある文字なら表示できるようです。
現在、開発中みたいなので、今後に期待。

●番外
IE7 => BOMがあったら削除する。
FireFox3 => BOMがある場合はそのまま残す。変更しない。
Opera => BOMがある場合はそのまま残す。変更しない。
Safari => BOMがある場合はそのまま残す。変更しない。
こんな感じみたいです。

#感想
ブラウザの表示についてはFireFox3がいい感じでした。
エディタはBabelPadが多言語の場合にはよさそうだけど、使い勝手は?
正規表現が使えれば、少し使い込んでみたかもだけど。良い選択肢の一つだとは思います。
Meadowも使い込めばよさそうな感触です。ただ、ちょっと敷居が高い感じ。
xyzzyは情報が豊富だし、カスタマイズがしやすそうですね。
プロポーショナルフォントが使えないのが、残念です。