テキストファイルのエンコーディングを自動検出する方法は?


69

バリアント文字セットでエンコードされた多くのプレーンテキストファイルがあります。

それらをすべてUTF-8に変換したいのですが、iconvを実行する前に、元のエンコーディングを知る必要があります。ほとんどのブラウザにはAuto Detectエンコーディングのオプションがありますが、あまりにも多くあるため、これらのテキストファイルを1つずつ確認することはできません。

元のエンコーディングのみがわかっているので、テキストをで変換できiconv -f DETECTED_CHARSET -t utf-8ます。

プレーンテキストファイルのエンコードを検出するユーティリティはありますか?100%完全である必要はありません。100万個のファイルが1,000,000個のファイルに誤って変換されていてもかまいません。

回答:


57

PyPiで利用可能なchardet Pythonモジュールを試してください。

pip install chardet

次にを実行しchardetect myfile.txtます。

Chardetは、Mozillaが使用する検出コードに基づいているため、入力テキストが統計分析に十分な長さであれば、妥当な結果が得られます。プロジェクトのドキュメントを読んでください。

コメントで述べたように、それは非常に遅いですが、@ Xavierがhttps://superuser.com/a/609056で見つけたように、一部のディストリビューションは元のC ++バージョンも出荷しています。Javaバージョンもどこかにあります。


3
はい、python-chardetUbuntuユニバースリポジトリのように既にパッケージ化されています。
謝Jìléi

完全な推測ではなかった場合chardetでも、のように、最も正確に推測でき./a.txt: GB2312 (confidence: 0.99)ます。失敗したばかりのEncaと比較して、「認識されないエンコーディング」を報告します。しかし、悲しいことに、chardet非常に遅いです。
謝Jìléi

1
@谢继雷:それを一晩実行するか、そのようなものにします。文字セットの検出がある複雑なプロセス。また、JavaベースのjChardetを試すこともできます...または元のchardetMozillaの一部ですが、C ++ソースのみが利用可能で、コマンドラインツールはありません。
-grawity

2
速度について:実行chardet <(head -c4000 filename.txt)ははるかに速く、私のユースケースでも同様に成功しました。(場合には、このbashの構文はchardetにのみ最初の4000のバイトを送信しますはっきりしていない)
ndemou

@ndemou私が持っているchardet==3.0.4、とコマンドラインツールの実際の実行可能ファイル名があるchardetectではありませんchardet
-Devy

32

この単純なコマンドを使用します。

encoding=$(file -bi myfile.txt)

または、実際の文字セット(などutf-8)のみが必要な場合:

encoding=$(file -b --mime-encoding myfile.txt)

4
残念ながら、fileUTF-8やUTF-16などの特定のプロパティを持つエンコーディングのみが検出されます。残りの-古いISO8859またはそのMS-DOSとWindowsの特派員-はchardet、99%の信頼度で検出するファイルであっても、「unknown-8bit」または類似のものとしてリストされます。
悲しみ

6
ファイルはiso-8859-1を示しました
cweiske

拡張機能が嘘をついている場合はどうなりますか?
james.garriss 14年

2
@ james.garriss:ファイル拡張子は(テキスト)コンテンツエンコーディングとは関係ありません。
メストレリオン

29

DebianベースのLinuxでは、uchardetパッケージ(Debian / Ubuntu)がコマンドラインツールを提供します。パッケージの説明の下を参照してください。

 universal charset detection library - cli utility
 .
 uchardet is a C language binding of the original C++ implementation
 of the universal charset detection library by Mozilla.
 .
 uchardet is a encoding detector library, which takes a sequence of
 bytes in an unknown character encoding without any additional
 information, and attempts to determine the encoding of the text.
 .
 The original code of universalchardet is available at
 http://lxr.mozilla.org/seamonkey/source/extensions/universalchardet
 .
 Techniques used by universalchardet are described at
 http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html

3
ありがとう!プロジェクトのホームページから、CLIが含まれていることは私には明らかではありませんでした。uchardetHomebrewを使用してインストールする場合、OS Xでも使用できます。
ステファンシュミット

1
ISO 8859-1文書がWindows-1252として誤って識別されたが、印刷可能な範囲でWindows-1252はISO 8859-1のスーパーセットであるため、最初は少し混乱していましたiconv
ステファンシュミット

16

Linuxにはencaがあり、Solarisにはauto_efを使用できます。


Enca は私には厳しすぎるようです:enca -d -L zh ./a.txtメッセージで失敗しました./a.txt: Unrecognized encoding Failure reason: No clear winner.@grawityが述べたように、chardetより緩いですが、それでもまだ遅すぎます。
謝Jìléi

10
Encaは「実際に何かをする」テストに完全に失敗します。
マイケルウルフ

1
uchardetは失敗しました(実際のCP1250ではなくCP1252を検出しました)が、encaは正常に機能しました。(単一の例、一般化するのは難しい...)
パロ


2

chardet(python 2.?)に戻ると、この呼び出しで十分かもしれません。

python -c 'import chardet,sys; print chardet.detect(sys.stdin.read())' < file
{'confidence': 0.98999999999999999, 'encoding': 'utf-8'}

完璧にはほど遠いものの....

echo "öasd" | iconv -t ISO-8859-1 | python -c 'import chardet,sys; print chardet.detect(sys.stdin.read())'
{'confidence': 0.5, 'encoding': 'windows-1252'}

2

Emacsを定期的に使用している人にとっては、次のものが便利だと思われるかもしれません(手動で変換を検査および検証できます)。

さらに、Emacsの文字セット自動検出は、他の文字セット自動検出ツール(chardetなど)よりもはるかに効率的であることがよくあります。

(setq paths (mapcar 'file-truename '(
 "path/to/file1"
 "path/to/file2"
 "path/to/file3"
)))

(dolist (path paths)
  (find-file path)
  (set-buffer-file-coding-system 'utf-8-unix)
  )

次に、このスクリプトを引数として(「-l」オプションを参照)Emacsを単純に呼び出すと、ジョブが実行されます。



0

isutf8moreutilsパッケージから)仕事をしました


2
どうやって?この答えはあまり役に立ちません。
モーセ

1
正確に尋ねられたわけではありませんが、便利なツールです。ファイルが有効なUTF-8の場合、終了ステータスはゼロです。ファイルが有効なUTF-8でない場合、または何らかのエラーがある場合、終了ステータスはゼロ以外です。
トン

0

また、ファイル-iが不明の場合

以下のような文字セットを推測できるこのphpコマンドを使用できます。

phpでは、以下のように確認できます。

エンコードリストを明示的に指定する:

php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), 'UTF-8, ASCII, JIS, EUC-JP, SJIS, iso-8859-1') . PHP_EOL;"

より正確な " mb_list_encodings ":

php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), mb_list_encodings()) . PHP_EOL;"

ここで最初の例では、一致する可能性のあるエンコードのリスト(リストの順序を検出)を配置していることがわかります。より正確な結果を得るには、次の方法ですべての可能なエンコードを使用できます:mb_list_encodings()

注意mb_ *関数にはphp-mbstringが必要です

apt-get install php-mbstring 

回答を参照してください:https : //stackoverflow.com/a/57010566/3382822

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