skmks

In order to make an apple pie from scratch, you must first create the universe.

コマンドラインでUTF-8テキストのBOMを追加したり削除したりする

このエントリーをはてなブックマークに追加

11 3月 2011 by skmk

BOM(バイト順マーク)を削除することはよくあるんだけど、つけたことってあまりなかった。 エディタの機能を使えばできるものもあるけど、大量なファイルをいちいちエディタで開いて処理するわけにもいかないので、コマンドでまとめて処理したい、そんなとき。

結論としては、nkf を使えば割と手軽にBOMを付けたり消したりできる。 「BOMのマークの文字なんだったっけ?」とか考えなくてもよい方法


2014/02/14 追記

これを書いた当時なぜか頑なにnkfだけは使うまいという謎のポリシーを持っていて、すごくまわりくどい説明になっていました。 意外と検索でひっかかってくる人がいるので、いたまれない気持ちではいたのですが、 なんとなく待っていた「それnkfでできるよ」が、ついにやって来たので、3年越しでついに重い腰をあげました。

以下の例はファイルfilenameの文字コードがUTF-8の場合です。

BOM追加

nkf --overwrite -oc=UTF-8-BOM filename

BOMつける場合は大抵Windows向けなので勝手に改行コードがCRLFになります。改行コードの指定を明示するなら-Lwですね。

BOM削除

nkf --overwrite -oc=UTF-8 filename

改行コードは維持されるので、CRを削除したい場合には-Luを明示的につけるとよいです。

追記は以上


なんでBOMつけようとか思ったの

Windowsにつけろって言われたから。

VC++はBOM付きUTF-8

UTF-8はバイト順に依らないので、本当はBOMは要らないのだけどWindowsのVisual Studio C++では、BOM付きじゃないとUTF-8で書かれてるかどうか判断できないらしい。

ソースにマルチバイト文字を含んでる場合にはコンパイル時にC4819という警告が出て、正しく動作しないことがある。

ソースコードにUTF-8を使う場合はBOMつきのみサポート。

gccはどっちでもよい

でもgccはBOMどうなの?と思ったらBOM付きで問題なくコンパイルできる。この辺で直ったようだ BOM付けてはいけないみたいな文書を見かけるが、イマドキは意外と付いててもなんとかなる。


以下OBSOLETE

BOM(バイト順マーク)を削除することはよくあるんだけど、つけたことってあまりなかった。 エディタの機能を使えばできるものもあるけど、大量なファイルをいちいちエディタで開いて処理するわけにもいかないので、コマンドでまとめて処理したい、そんなとき。 結論としては、uconv を使えば割と手軽にBOMを付けたり消したりできる。 「BOMのマークの文字なんだったっけ?」とか考えなくてもよい方法

BOMの確認

fileコマンドを使う。

$ file *.cpp
foo.cpp:   UTF-8 Unicode text
bar.cpp:   UTF-8 Unicode (with BOM) text

BOMが付いてるテキストは「(with BOM)」となるので、エディタなどで開かずにBOMが付いてるかどうかを確認できる。

現在のディレクトリ以下にあるC++のソースファイル(c,h,cpp,hpp)でBOMが付いてないファイルのファイル名を取り出すには

find . -type f \( -name '*.[ch]' -o -name '*.cpp' -o -name '*.hpp' \) -exec file {} + | grep -v "(with BOM)" | cut -d: -f1

BOMが付いてるファイル名を取り出すにはgrep-vを取って、

find . -type f \( -name '*.[ch]' -o -name '*.cpp' -o -name '*.hpp' \) -exec file {} + | grep "(with BOM)" | cut -d: -f1

BOMの追加と削除

uconvを使う。 詳しくは、

International Components for Unicode http://site.icu-project.org/

debianの場合最初から使えたけど、ない人はaptitudeでlibicu-dev辺りを入れればいいんだと思う。 Windowsのバイナリもある。

BOMを追加する

uconv -f utf-8 -t utf-8 --add-signature foo.cpp > foo_bom.cpp

BOMを削除する

uconv -f utf-8 -t utf-8 --remove-signature bar.cpp > bar_nobom.cpp

出力ファイルに入力ファイルと同じ名前を指定して消してしまわないように注意。 -f-tはプラットホームのエンコーディングがutf-8以外の場合は省略するとうまくいかないことがあるので明示してる。

localeコマンドを実行してLANG=ja_JP.utf8とかだったら-f,-tオプションは省略できるよ。

上のBOMの確認の例と組み合わせれば、お手軽にまとめて変換できるね。

6 comments | Categories: bash, C++, Windows | Tags:

Comments (6)

  1. Pingback: プログラミング参考サイト | android manifest configChanges

  2. Pingback: WindowsでファイルのBOMを付けたり消したりする | 秋元

  3. Pingback: Visual C++ 2010 と gcc 共有ソースでの文字コードについて | DeVlog - 銀の翼で翔べ -

  4. nkf でできませんか?

  5. -ocがアンノウンオプションって言われるので調べたら
    –ocが正しいようです
    記事から2年経って変わったのかな

Leave a Reply

Required fields are marked *