Como posso testar a codificação de um arquivo de texto ... É válido e o que é?

46

Eu tenho vários .htmarquivos que abrem no Gedit sem nenhum aviso / erro, mas quando eu abro esses mesmos arquivos Jedit, ele me avisa sobre a codificação UTF-8 inválida ...

A meta tag HTML indica "charset = ISO-8859-1". O Jedit permite uma lista de codificações de fallback e uma lista de detectores automáticos de codificação (atualmente "BOM XML-PI"), portanto meu problema imediato foi resolvido. Mas isso me fez pensar: e se os metadados não estivessem lá?

Quando as informações de codificação simplesmente não estão disponíveis, existe um programa CLI que pode "adivinhar" quais codificações podem ser aplicadas?

E, embora seja uma questão um pouco diferente; existe um programa CLI que testa a validade de uma codificação conhecida ?

Peter.O
fonte
Semelhante a "Como detectar automaticamente a codificação de arquivo de texto?" superuser.com/questions/301552/…
buzz3791
Veja também stackoverflow.com/q/805418/821436 :-)
Reinstate Monica - M. Schröder

Respostas:

60

O filecomando faz "melhores palpites" sobre a codificação. Use o -iparâmetro para forçar filea impressão de informações sobre a codificação.

Demonstração:

$ file -i *
umlaut-iso88591.txt: text/plain; charset=iso-8859-1
umlaut-utf16.txt:    text/plain; charset=utf-16le
umlaut-utf8.txt:     text/plain; charset=utf-8

Aqui está como eu criei os arquivos:

$ echo ä > umlaut-utf8.txt 

Hoje em dia tudo é utf-8. Mas convença-se:

$ hexdump -C umlaut-utf8.txt 
00000000  c3 a4 0a                                          |...|
00000003

Compare com https://en.wikipedia.org/wiki/Ä#Computer_encoding

Converta para as outras codificações:

$ iconv -f utf8 -t iso88591 umlaut-utf8.txt > umlaut-iso88591.txt 
$ iconv -f utf8 -t utf16 umlaut-utf8.txt > umlaut-utf16.txt 

Verifique o dump hexadecimal:

$ hexdump -C umlaut-iso88591.txt 
00000000  e4 0a                                             |..|
00000002
$ hexdump -C umlaut-utf16.txt 
00000000  ff fe e4 00 0a 00                                 |......|
00000006

Crie algo "inválido" misturando os três:

$ cat umlaut-iso88591.txt umlaut-utf8.txt umlaut-utf16.txt > umlaut-mixed.txt 

O que filediz:

$ file -i *
umlaut-iso88591.txt: text/plain; charset=iso-8859-1
umlaut-mixed.txt:    application/octet-stream; charset=binary
umlaut-utf16.txt:    text/plain; charset=utf-16le
umlaut-utf8.txt:     text/plain; charset=utf-8

sem -i:

$ file *
umlaut-iso88591.txt: ISO-8859 text
umlaut-mixed.txt:    data
umlaut-utf16.txt:    Little-endian UTF-16 Unicode text, with no line terminators
umlaut-utf8.txt:     UTF-8 Unicode text

O filecomando não tem idéia de "válido" ou "inválido". Ele vê apenas alguns bytes e tenta adivinhar qual pode ser a codificação. Como seres humanos, podemos reconhecer que um arquivo é um arquivo de texto com alguns tremados em uma codificação "errada". Mas, como um computador, seria necessário algum tipo de inteligência artificial.

Alguém poderia argumentar que a heurística de fileé algum tipo de inteligência artificial. No entanto, mesmo que seja, é muito limitado.

Aqui está mais informações sobre o filecomando: http://www.linfo.org/file_command.html

lesmana
fonte
Obrigado, funcionou ... Eu tinha tentado 'arquivo , but without any option :( ... I've now also tried a mixof UTF-16 and UTF-8 and ISO-8859-1. arquivo -i` relatado unknown-8bit. Então, isso também parece ser a resposta para: "Como detectar um / codificação desconhecida inválido"
Peter.O
Para quem chega aqui e está no mac, é file -Icom um 'i' maiúsculo em vez de minúsculo.
samuraiseoul 17/07
21

Nem sempre é possível descobrir com certeza qual é a codificação de um arquivo de texto. Por exemplo, a sequência de bytes \303\275( c3 bdem hexadecimal) pode estar ýem UTF-8, ou ýem latin1, ou Ă˝em latin2, ou em BIG-5, e assim por diante.

Algumas codificações têm seqüências de bytes inválidas, portanto é possível descartá-las com certeza. Isso é verdade principalmente do UTF-8; a maioria dos textos na maioria das codificações de 8 bits não é UTF-8 válida. Você pode testar para UTF-8 válida com isutf8a partir moreutils ou com iconv -f utf-8 -t utf-8 >/dev/null, entre outros.

Existem ferramentas que tentam adivinhar a codificação de um arquivo de texto. Eles podem cometer erros, mas geralmente funcionam na prática, desde que você não tente enganá-los deliberadamente.

  • file
  • PerlEncode::Guess (parte da distribuição padrão) tenta codificações sucessivas em uma sequência de bytes e retorna a primeira codificação na qual a sequência é um texto válido.
  • Enca é um adivinho e conversor de codificação. Você pode atribuir a ele o nome e o texto do idioma que você presume estar nesse idioma (os idiomas suportados são principalmente os idiomas da Europa Oriental) e tenta adivinhar a codificação.

Se houver metadados (HTML / XML charset=, TeX \inputenc, emacs -*-coding-*-,…) no arquivo, editores avançados como o Emacs ou o Vim geralmente poderão analisar esses metadados. Isso não é fácil de automatizar a partir da linha de comando.

Gilles 'SO- parar de ser mau'
fonte
Obrigado pela boa visão geral ... Sim, "adivinhar" pode ser a única opção quando a codificação não é conhecida ... Usando iconv, eu apenas executei todas as 1168 codificações (incluindo aliases) listadas em iconv -lum dos meus arquivos .htm ... Havia 683 codificações que passaram na reunião .. O conjunto de caracteres real do arquivo = ISO-8859-1 .. composto por todos os valores de intervalo ASCII da barra um .. O caractere não ASCII era \ xA9.
perfil completo de Peter
0

Também no caso de você arquivar -i, você não sabe

Você pode usar este comando php que pode adivinhar o charset como abaixo:

No php você pode conferir como abaixo:

Especificando lista de codificação explicitamente:

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 " mais preciso :

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

Aqui no primeiro exemplo, você pode ver que eu coloquei uma lista de codificações (detectar a ordem da lista) que podem estar correspondentes. Para obter resultados mais precisos, você pode usar todas as codificações possíveis em: mb_list_encodings ()

Nota As funções mb_ * requerem php-mbstring

apt-get install php-mbstring 

Consulte a resposta: https://stackoverflow.com/a/57010566/3382822

Mohamed23gharbi
fonte