Metin dosyası kodlamasını otomatik olarak nasıl saptayabilirim?


69

Değişken karakter kümelerinde kodlanmış birçok düz metin dosyası vardır.

Hepsini UTF-8'e dönüştürmek istiyorum, ancak iconv komutunu çalıştırmadan önce orijinal kodlamasını bilmem gerekiyor. Çoğu tarayıcı Auto Detectkodlamada bir seçeneğe sahiptir, ancak bu metin dosyalarını tek tek kontrol edemiyorum çünkü çok fazla var.

Sadece orijinal kodlamayı bilerek, o zaman metinleri dönüştürebilirim iconv -f DETECTED_CHARSET -t utf-8.

Düz metin dosyalarının kodlamasını tespit etmek için herhangi bir yardımcı program var mı? % 100 mükemmel olmak zorunda DEĞİLDİR, 1.000.000 dosyada yanlış dönüştürülmüş 100 dosya olup olmadığını umursamıyorum.

Yanıtlar:


57

PyPi'de bulunan chardet Python modülünü deneyin :

pip install chardet

O zaman koş chardetect myfile.txt.

Chardet, Mozilla tarafından kullanılan tespit koduna dayanmaktadır , bu nedenle girdi metninin istatistiksel analiz için yeterince uzun olması şartıyla makul sonuçlar vermesi gerekir. Proje belgelerini okuyunuz .

Yorumlarda belirtildiği gibi oldukça yavaştır, ancak bazı dağıtımlar orijinal C ++ sürümünü de, @Xavier'nin https://superuser.com/a/609056 adresinde bulduğu şekilde gönderir . Ayrıca bir yerde bir Java sürümü var.


3
Evet, zaten python-chardetUbuntu evren deposunda olduğu gibi paketlendi .
Xiè Jìléi

Mükemmel bir tahmin olmasaydı chardet, yine de en doğru tahminde bulunmaya devam edecek ./a.txt: GB2312 (confidence: 0.99). Sadece başarısız olan ve 'Tanınmayan kodlama' raporunu veren Enca ile karşılaştırıldı. Ancak ne yazık ki, yeterince chardetyavaş çalışıyor.
Xiè Jìléi

1
@ 谢 继 雷: Bir gece ya da onun gibi bir şeyle çalışmasını sağlayın. Karakter algılama olan bir karmaşık bir süreç . Ayrıca, orijinal ... Java tabanlı jChardet veya deneyebilirsiniz Chardet olan Mozilla parçası , ama sadece C ++ kaynak, hiçbir komut satırı aracı mevcuttur.
yerçekimi

2
Hız konusunda: chardet <(head -c4000 filename.txt)kullanım durumumda koşmak çok daha hızlı ve eşit derecede başarılıydı. (bu bash sözdiziminin chardet'e yalnızca ilk 4000 byte göndereceği açık değilse)
ndemou

@ Sahip olduğum chardet==3.0.4ve komut satırı aracının gerçek yürütülebilir adı chardetectdeğil chardet.
Devy

32

Bu basit komutu kullanırdım:

encoding=$(file -bi myfile.txt)

Veya sadece gerçek karakter setini (gibi utf-8) istiyorsanız :

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

4
Ne yazık ki, fileyalnızca UTF-8 veya UTF-16 gibi belirli özelliklere sahip kodlamaları algılar. Kalan - eski ISO8859 ya da MS-DOS ve Windows muhabirleri - " chardet% 100 güvenle algılayan dosyalar için bile" bilinmeyen 8 bit "ya da benzer bir şey olarak listeleniyor .
yerçekimi

6
dosya bana iso-8859-1 gösterdi
cweiske

Ya uzatma yalan söylüyorsa?
james.garriss,

2
@ james.garriss: dosya uzantısının (text) içerik kodlaması ile ilgisi yok.
MestreLion

29

Debian tabanlı Linux'ta, uchardet paketi ( Debian / Ubuntu ) bir komut satırı aracı sağlar. Paket açıklamasına bakınız:

 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
Teşekkürler! Projenin ana sayfasından, CLI'nin dahil olduğu açıkça belli değildi. uchardetHomebrew üzerinden kurulum yaparken OS X'te de mevcuttur .
Stefan Schmidt,

1
Bir ISO 8859-1 belge sahte Windows 1252 olarak tespit edilen ilk Çünkü başta biraz karışık oldu ama yazdırılabilir aralık Windows 1252 yılında ISO 8859-1 ile çok dönüşüm bir üst kümesidir iconvince işler.
Stefan Schmidt,

16

Linux için, enca var ve Solaris için auto_ef kullanabilirsiniz .


: Enca benim için çok sıkı görünüyor enca -d -L zh ./a.txtmesajla başarısız ./a.txt: Unrecognized encoding Failure reason: No clear winner., söz @grawity olarak chardetancak henüz çok yavaş, daha gevşek.
Xiè Jìléi

10
Enca “aslında bir şeyler yapıyor” testini tamamen başarısızlıkla sonuçladı.
Michael Wolf

1
uchardet başarısız oldu (gerçek CP1250 yerine CP1252 tespit edildi), ancak enca iyi çalıştı. (tek örnek, genelleştirmek zor ...)
Palo


2

Chardet'e geri dönmek (python 2.?) Bu çağrı yeterli olabilir:

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

Mükemmel olmaktan uzak olsa da ....

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

Düzenli olarak Emacs kullananlar için, aşağıdakileri yararlı bulabilirler (transfomasyonu elle kontrol etmenizi ve doğrulamanızı sağlar).

Ayrıca, Emacs'in char-set otomatik algılama özelliğinin, diğer char-set otomatik algılama araçlarından (örneğin, chardet) çok daha etkili olduğunu da sık sık buluyorum.

(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)
  )

Ardından, bu komut dosyasıyla Emacs'a basit bir çağrı (argüman olarak bakınız "-l" seçeneğine bakın) işi yapar.



0

isutf8( moreutilspaketten) işi yaptı


2
Nasıl? Bu cevap pek yardımcı değil.
Musa,

1
Tam olarak sorulmadı, ancak yararlı bir araçtır. Dosya UTF-8 geçerliyse, çıkış durumu sıfırdır. Dosya UTF-8 geçerli değilse veya bir hata varsa, çıkış durumu sıfır değildir.
ton

0

Ayrıca -i dosyanız durumunda, bilinmeyen bir şey veriyorsa

Karakter kümesini aşağıdaki gibi tahmin edebilen bu php komutunu kullanabilirsiniz:

PHP'de aşağıdaki gibi kontrol edebilirsiniz:

Kodlama listesini açıkça belirtme:

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

Daha doğru " mb_list_encodings ":

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

Burada ilk örnekte, eşleşen olabilecek kodlamaların bir listesini koyduğumu (liste sırasını algıladığımı) görebilirsiniz. Daha kesin sonuç almak için, mümkün olan tüm kodlamaları: mb_list_encodings () ile kullanabilirsiniz.

Not mb_ * işlevleri php-mbstring gerektirir

apt-get install php-mbstring 

Cevabı gör: https://stackoverflow.com/a/57010566/3382822

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.