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の確認の例と組み合わせれば、お手軽にまとめて変換できるね。
5件のコメント
inok · 2014/02/14 01:09
nkf でできませんか?
skmk · 2014/02/14 03:01
できます!記事直しました!
プログラミング参考サイト | android manifest configChanges · 2013/02/05 21:24
[…] コマンドラインでUTF-8テキストのBOMを追加したり削除したりする […]
WindowsでファイルのBOMを付けたり消したりする | 秋元 · 2013/03/11 21:04
[…] 対処法としては、「コマンドラインでUTF-8テキストのBOMを追加したり削除したりする」に書いてあることを実施しているだけですが。 […]
Visual C++ 2010 と gcc 共有ソースでの文字コードについて | DeVlog - 銀の翼で翔べ - · 2013/07/29 00:28
[…] コマンドラインでUTF-8テキストのBOMを追加したり削除したりする | skmks Category: C++, Linux, Windows Tag: gcc, Qt, VisualC++ 2013年7月29日 at 00:28 No comments J-run Leave a Comment or Cancel reply […]