比嘉です。二度目の投稿になります。
Macで開発していると、ときたまBOM付きファイルに遭遇してしまい
謎のエラーに悩まされることがあります。
実はこの記事を書いているときも、BOM付きファイルに悩まされていました…。
BOMとは
BOMとは、バイトオーダーマーク(Byte Order Mark)の略で、Unicodeのエンコーディング方式(UTF-8やUTF-16など)のファイルの先頭に、
符号化情報を付与する目的で記入されるものです。
BOMは必須情報ではないため、BOM付きとBOMなしの2種類のエンコーディングが存在します。
言語やプログラムによっては、BOMを文字として扱うことがあるため、
エディタ上では問題なく見えるプログラムが、動作させるとエラーを吐くことがあります。
BOM付きファイルに遭遇してしまった場合、まずはBOM付きファイルの抽出を行い、
BOM付きファイルを特定した後、BOMを削除する必要があります。
手作業でエディタでファイルを一つずつ開いて確認するわけにもいかないので、
BOM付きファイルを抽出し、BOM削除を行うコマンドを紹介します。
BOM付きファイルを抽出するコマンド
BOM付きファイルを抽出するコマンドを2例紹介します。インターネット上には、findコマンドでBOM付きファイルを見ると「(with BOM)」と
表示されるという情報がありましたが、私の環境では表示されないファイルもあるので、
直接バイト列を指定しています。
BOM付きファイルを抽出するコマンド1
1 |
find . -name '*.php' | xargs grep -l ^$'\xef\xbb\xbf' |
findとgrepを組み合わせたオーソドックスなコマンドです。
bashの力を借りて16進数のバイト列でBOMを指定しています。
BOM付きファイルを抽出するコマンド2
1 |
grep -lr --include="*.php" ^$'\xef\xbb\xbf' . |
grepのみで行うコマンドです。
抽出したBOM付きファイルからBOMを削除するコマンド
抽出したBOM付きファイルからBOMを削除するコマンドですが、これが少し大変でした。インターネット上には、sedやawkを使う情報やviで処理をする方法などがありましたが、
今回はviを使って「set nobomb」する方法を使用します。
下記のコマンドで、抽出したファイルをfor文で回しながらviに渡し「set nobomb」しています。
BOMを抽出し削除するコマンド
1 |
for textfile in $( find . -name '*.php' | xargs grep -l ^$'\xef\xbb\xbf' ); do vi -c "set nobomb" -c wq! "${textfile}"; done |
for文に渡すコマンドは、上記「BOM付きファイルを抽出するコマンド1」を使用していますが、
もちろん「BOM付きファイルを抽出するコマンド2」でも同じ結果となります。
大したことをしている訳ではないのですが、
少しでもBOMに悩まされている人の助けになれば幸いです。