UTF-8ファイルからBOMを削除するにはどうすればよいですか?


64

BOMを使用したUTF-8エンコードのファイルがあり、BOMを削除したい。ファイルからBOMを削除するLinuxコマンドラインツールはありますか?

$ file test.xml
test.xml:  XML 1.0 document, UTF-8 Unicode (with BOM) text, with very long lines


1
数か月前にそれを行うための非常に簡単なツールを作成しました:oskog97.com/read/?path= / small-scripts / killbom&referer= / / usr / local / binにそのようなものをインストールする価値があるBOMを含む多くのUTF-8エンコードファイルがあります。
オスカースコグ

回答:


76

ファイルにUTF-8 BOMが含まれているかどうかわからない場合はsed、BOMが存在する場合はこれを削除し(GNU実装を想定)、存在しない場合は変更を行いません。

sed '1s/^\xEF\xBB\xBF//' < orig.txt > new.txt

次の-iオプションを使用して、既存のファイルを上書きすることもできます。

sed -i '1s/^\xEF\xBB\xBF//' orig.txt

4
これはutf8ロケールでは機能しない可能性がありますが、cまたはposixにロケールオーバーライドを付加すると常に機能します。
17

3
@hildred en_US.UTF-8ロケールでテストし、動作しました。いつ失敗しますか?
m13r

2
@ m13r、これはsedおよびコンパイルオプションのバージョンに依存します。失敗した場合、Unicode文字クラスを備えたsedの非常に新しいバージョンは、3バイトシーケンスを、3文字シーケンスと一致しない単一の文字として取り込みます。ただし、このような場合、16ビットの文字一致を実行できます。ただし、これは新しい機能であり、普遍的に存在するものではありません。テストする場合は、最新バージョンをコンパイルすることをお勧めします。
17

4
ユニコード対応のsedで動作するように修正するには、LC_ALL = C sed '1s / ^ \ xEF \ xBB \ xBF //'
ジョシュア

1
@mazunkiは1s/、最初の行のみを検索することを意味します。他の行は影響を受けません。この^手段は、(最初​​の)行の先頭でのみ一致します。\xEF\xBB\xBFUTF-8 BOM(エスケープされた16進文字列)です。//何も置き換えないことを意味します。1最後に(for 1s/^xEF\xBB\xBF//1)を追加することもできますが、これはその行で最初に出現したパターンにのみ一致することを意味します。ただし、検索はに固定されている^ため、違いはありません。ファイルの最初の行の先頭にBOMがない場合、パターンは一致しないため、変更は行われません。
CSM

64

BOMはUTF-8では意味がありません。これらは通常、Microsoft OS上の偽のソフトウェアによって誤って追加されます。

dos2unix それを削除し、Windowsテキストファイルの他の特異性も処理します。

dos2unix test.xml

17
UTF-8でエンコードされたBOMは意味をなさないことに同意しますが、信じられないかもしれませんが、UTF-8を他の8ビットエンコードと区別するのに役立つ素晴らしいアイデアだと考える人が大勢います。だから、それは好みの問題です。Windowsメモ帳は、意図的にBOMを追加します。
ヨハンMyréen17年

17
コンテキストがそれを削除する方法に関する単なる質問である場合、それが理にかなっているかどうかは重要ですか?ウィキペディアによると、メモ帳はファイルをUTF-8として認識するためにBOMを必要とし、Google Docsはファイルをテキストとしてエクスポートする際にファイルを追加します。彼ら全員が間違ってそれをしているとは思えない。
-ilkkachu

コメントは詳細なディスカッション用ではありません。この会話はチャットに移動さました
テルドン

1
行末を変換せずにBOMを削除する方法はありdos2unixますか?
m13r

2
@ m13r次に、この回答でsedスクリプトを使用します。これにより、bom(存在する場合)のみが削除され、他は変更されません。
矢印

26

tail次のコマンドを使用して、ファイルからBOMを削除することができます。

tail -c +4 withBOM.txt > withoutBOM.txt

2
なぜ4?BOMには3バイトがあります。
-deviantfan

10
@deviantfanこれは、スキップする場合、4バイト目から開始する必要がある理由です。
ステファンシャゼラス

9
tail1ベースのインデックス作成を使用していますか?!WTF!
CodesInChaos

5
@CodesInChaos、tail -c -1またはtail -c 1tail一般的に使用される)はtail -c +1、最初のバイトから始まる最後のバイトから始まるコンテンツです。tail -c 0/ tail -c +0そのためには、ずっと直感的ではありません。
ステファンシャゼラス

2
@deviantfan: (dd bs=1 count=3 of=/dev/null; cat) <input >output。または、GNU (head -c3 >/dev/null; cat)で-UTF8または他の1バイト以外のロケールでも; GNUヘッドは 'char' = byteを実行します。
dave_thompson_085

20

VIMを使用する

  1. VIMでファイルを開く:

    vi text.xml
    
  2. BOMエンコードを削除します。

    :set nobomb
    
  3. 保存して終了:

    :wq
    

奇妙なことにMac上でvimの8で、私は、Excelで作ったcsv UTF-8のファイルを持っており、それはで始まる<feff>、まだ:set nobombそれを変更したり、削除されません。
ドラムブリン

5

使用できます

LANG=C LC_ALL=C sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- filename

ファイルの先頭からバイトオーダーマークがある場合は削除し、CR LF改行をLFのみに変換します。LANG=C LC_ALL=Cあなたは、コマンドがバイトオーダーマークを形成する3つのバイトがバイトとして扱われます(また、デフォルトのPOSIXロケールとして知られている)、デフォルトのCロケールで実行したいシェルに指示します。-ised のオプションはインプレースを意味します。を使用する-i.old場合、sedは元のファイルをとして保存しfilename.old、新しいファイル(変更がある場合は)をとして保存しますfilename


私は個人的にこれを持っているのが好き~/bin/fix-msです。たとえば、

#!/bin/dash
export LANG=C LC_ALL=C
if [ $# -gt 0 ]; then
    for FILE in "$@" ; do
        sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$FILE" || exit 1
    done
else
    exec sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//'
fi

すべてのCソースファイルとヘッダー(たとえば、MS-DOS時代の私の古いコード!)を言うためにこれを適用する必要がある場合は、実行するだけです。

find . -name '*.[CHch]' -print0 | xargs -r0 ~/bin/ms-fix

または、そのようなファイルを変更せずに見たいだけなら、実行できます

~/bin/ms-fix < filename | less

<U+FEFF>UTF-8ターミナルにい文字が表示されません。


なぜ単純ではないのですsed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$@"か?
ステファンシャゼラス

@StéphaneChazelas:置換に問題がある場合、すぐにスクリプトを終了したいので、sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$@"そうしません。終了コードを返しますが、終了する前に引数リストにリストされているすべてのファイルを処理します。
公称動物

@StéphaneChazelas:--もちろん、ファイル名の前は重要です。これがないと、ダッシュで始まるファイル名がsedによってオプションと見なされる場合があります。それらを回答に編集しました。リマインダーをありがとう!
公称動物

0

最近、任意のUTF-8エンコードファイルでBOMを追加または削除するこの小さなコマンドラインツールを見つけました。UTFBOM Utils(githubの新しいリンク

小さな欠点は、プレーンなC ++ソースコードのみをダウンロードできることです。メイクファイルを作成し(たとえばCMakeを使用)、自分でコンパイルする必要があります。このページではバイナリは提供されていません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.