奇妙な文字を含むUTF-8ファイルがあります。私の目には次のようになります。
<96>
これがどのように現れるかvi
そしてそれがどのように現れるかgedit
LibreOfficeに表示される方法
これにより、次のようなさまざまな基本的なUnixツールに問題が発生します。
cat file
キャラクターを消えるようにしてmore
、- vi/vimからコピーして貼り付けることはできません。それ自体を見つけることもできません。
grep
何も表示できません。まるでキャラクターが存在しないようです。
プログラムはfile
うまく動作し、UTF-8ファイルとして認識されます。また、ファイルの性質上、ウェブ上のコピーと貼り付けに由来した可能性が高く、その文字はもともとEMDASHを意味することも知っています。
私の基本的な質問は次のとおりです。
- このファイルに問題がありますか?
- 同じファイルから別のアイテムを検索するにはどうすればよいですか?
- 同じ問題/文字を含む可能性がある他のファイルを見つけるにはどうすればよいですか?
ドキュメントはここにあります:ファイル.txt
ベストアンサー1
ファイルにはバイトが含まれていますC2 96
。UTF-8コードポイントU + 0096のエンコード。このコードポイントは次のいずれかです。C1制御文字SPA「保護地域の開始」(または「保護地域」)とも呼ばれます。これは現代のシステムに役立つ文字ではありませんが、そうではない可能性もあります。有害そこにいます。
ソースソースは、おそらくどこかで誤ってトランスコードされたいくつかのシングルバイト8ビットエンコーディングのバイト0x96です。おそらくもともとこれでした。Windows CP1252ダッシュ「−」は、対応する符号化においてバイト値96を有する。他のほとんどの可能な候補は、位置80-9Fに制御セットを持っています。これはlatin-1のようにUTF-8に変換されました(ISO/IEC 8859-1)これは珍しいことではありません。見てわかるように、バイトは制御文字として解釈され、それに応じて変換されます。
iconv
glibcの一部であるこのツールを使用して、このファイルを修復できます。
iconv -f utf-8 -t iso-8859-1 < mwe.txt | iconv -f cp1252 -t utf-8
私にとっては、最小限の例の正しいバージョンを生成してください。まず、UTF-8をlatin-1に変換し(以前の誤った翻訳を裏返し)、再解釈します。それcp1252はそれをUTF-8に正しく変換します。
ただし、これは実際のファイルに何があるかによって異なります。他の場所にLatin-1以外の文字があると、最初のステップでその文字を正しくエンコードできないため失敗します。
iconvが存在しない場合、または実際のファイルで機能しない場合は、sedを使用してバイトを置き換えることができます。
LC_ALL=C sed -e $'s/\xc2\x96/\xe2\x80\x93/g' < mwe.txt
C2 96
これはダッシュエンコーディングをUTF-8に置き換えますE2 80 93
。たとえば、\xe2\x80\x93
に変更して1つまたは2つのハイフンに置き換えることもできます--
。
同様の方法でgrepを実行できます。物事を解釈するLC_ALL=C
のではなく、実際のバイトを読んでいることを確認するために使用するものgrep
:
LC_ALL=C grep -R $'\xc2\x96` .
このディレクトリにあるすべてのバイトエントリが一覧表示されます。コンテンツが混在している場合、バイナリファイルにはバイトペアが含まれることが多いため、テキストファイルのみに制限したい場合があります。