使用しようとするgrep
とおなじみの質問~のBOM(バイト順表示)Unicodeファイル(この場合はUTF-8)。具体的には、XYZ
パターンで始まるファイルを見つけようとしますgrep '^XYZ'
が、もちろんgrep
BOMは3つの別々の文字として扱われ、最初の行がで始まるとファイルの最初の行と一致しませんXYZ
。空白()を無視するように正規表現を更新しようとしましたが、'^[[:space:]]*XYZ'
役に立ちませんでした。
他の問題が解決されました。ファイル変換または特にBOM用しかし、POSIXツールにUnicodeファイルを正しく処理するための共通オプションがあるかどうかを知りたいです。 Unicodeファイルを正しく処理すると、grep
ファイルの内容はBOMの後ろから始まり、他の行とXYZ
同じように最初の行で一致すると思います。
答え1
Unicodeコンソーシアムには、次のFAQがあります。BOMをどのように処理しますか?。このセクションには以下が含まれます。
テキストデータストリームが純粋なUnicodeテキストであることがわかっていますが、どのエンディアンであるかわからない場合は、BOMを署名として使用できます。 BOMがない場合、テキストはビッグエンディアンとして解釈する必要があります。
そして
データストリームの正確なタイプがわかっている場合(UnicodeビッグエンディアンやUnicodeリトルエンディアンなど)、BOMを使用しないでください。特に、データストリームがUTF-16BE、UTF-16LE、UTF-32BE、またはUTF-32LEとして宣言されるたびにBOMを使用しないでください。
UTF-8はいつもエンディアンがないのでエンディアンとして知られています。したがって、テキストがUTF-8であることを知っている限り、「BOMを使用しないでください」。
BOMを不必要に使用しても、cat
最初のファイルを除くすべてのファイルのBOMは、幅0の改行なしの空白として扱われるため、誤った結果が返されます。しかし、UNIXの力はフィルタにあります。
単一のファイルまたはストリームに対する操作の場合、sed "1s/^$(printf '\357\273\277')//"
BOM(存在する場合)がパイプラインから削除され、他のすべてのストリームは変更されません。
複数のファイルを扱う場合は、プロセス置換シェル(Bashに似ていますが、残念ながらPOSIXシェルではありません)が便利です。
sb() { sed "1s/$(printf '\357\273\277')//" "$@" ; }
cat <(sb file1) <(sb file2) …
答え2
ほとんどのPOSIXツールは文字ではなくバイトとして機能します。 Unicode信号は意味がないので、他のデータと同じように扱われます。
答え3
~からもう一つの答え、無効なBOM署名を持つファイルを処理しているようです。
だから答えはPOSIXツールはすでにUnicode(UTF-8)ファイルを正しく処理します。
Unicodeが間違っている場合は、もちろん正しく処理されませんが、次のものを使用できます。他の質問でのBOMの位置決め冗長BOM署名を処理します。