Convertendo um arquivo UTF-8 para ASCII (melhor esforço)

23

Eu tenho um arquivo em UTF-8 que contém textos em vários idiomas. Muitos são nomes de pessoas. Preciso convertê-lo para ASCII e preciso que o resultado pareça o mais decente possível.

Existem várias maneiras de abordar a conversão de uma codificação mais ampla para uma mais estreita. A transformação mais simples seria substituir todos os caracteres não ASCII por algum espaço reservado, como '_'. Se eu sei o idioma em que o arquivo está escrito, há possibilidades adicionais, como romanização.

Que ferramenta Unix ou biblioteca de linguagem de programação disponível no Unix pode me proporcionar uma conversão decente (com o melhor esforço) de UTF-8 para ASCII?

A maior parte do texto está em idiomas europeus, baseados no tipo latino.

user7610
fonte
1
você sabe onde começa o idioma? Há, por exemplo, uma diferença em como lidar com a indisponibilidade de um trema (como no ö). Em alemão, você sempre pode escrever "oe", mas, por exemplo, em holandês, a indisponibilidade de um trema pode ser melhor "descrita" por um traço seguido pelo caractere treinado (e aí o "oe" seria um ditongo completamente diferente)
Anthon
Como você define "o mais decente possível"? A verdadeira dificuldade está em definir os mapeamentos. Comparado a isso, a tarefa de programação é trivial. Os mapeamentos realmente usados ​​variam muito e podem ser específicos de um idioma de duas maneiras: eles dependem do idioma do texto e do idioma assumido pelo leitor (especialmente no que diz respeito à romanização).
Jukka K. Korpela
@ JukkaK.Korpela "o mais decente possível" é definido por aqueles que criaram a "ferramenta Unix ou a biblioteca de linguagem de programação disponível no Unix" que estou solicitando. Se o melhor que vou conseguir é substituir tudo que não seja ASCII por um sublinhado, não há muito mais que eu possa fazer. Exceto escrevendo minha própria ferramenta, que não vou. Eu acho Unix @ SO pode não ser o melhor lugar para esta pergunta ...
user7610
1
@ user7610 Diferente de iconve tr, existe o Unidecode . Eu não estou familiarizado com isso, mas pode fazer o que você quiser, se você puder usar o Python.
yellowantphil
1
@yellowantphil ou unidecode do no JavaScript / nó, UnidecodeSharp em C♯ ou Text :: Unidecode no Perl, que passa a ser o primeiro desse nome. Eu acho que existem outras versões.
usar o seguinte comando

Respostas:

11
konwert utf8-ascii

Ele fará a conversão de melhor esforço, dependendo das tabelas de conversão. Se você conhece aproximadamente o idioma de entrada, existem filtros específicos do idioma que fornecem melhores resultados, por exemplo

konwert utf8-xmetodo

é a conversão do esperanto na representação x-metodo,

konwert UTF8-tex

tentará fazer uma representação teocrática dos diacríticos, existem parâmetros específicos do idioma:

konwert UTF8-ascii/de

transliterará "ä" para "ae" (habitual para o alemão) em vez de simples "a"

konwert UTF8-ascii/rosyjski

usará regras polonesas para transliterar o russo, em vez das regras "do tipo inglês", etc ...

Radovan Garabík
fonte
Esta é a localização mais recente do konwertsite? É empacotado em algum lugar? github.com/taw/konwert/tree/master/konwert-1.8
Nemo
25

Isso funcionará para algumas coisas:

iconv -f utf-8 -t ascii//TRANSLIT

echo ĥéĺłœ π | iconv -f utf-8 -t ascii//TRANSLITretorna helloe ?. Quaisquer caracteres que iconvnão sabem como converter serão substituídos por pontos de interrogação.

iconvé POSIX, mas não sei se todos os sistemas têm a TRANSLITopção Funciona para mim no Linux. Além disso, a IGNOREopção descartará silenciosamente caracteres que não podem ser representados no conjunto de caracteres de destino (consulte man iconv_open).

Uma opção inferior, mas compatível com POSIX, é usar tr. Este comando substitui todos os pontos de código não ASCII por um ponto de interrogação. Ele lê texto UTF-8, um byte de cada vez. "É" pode ser substituído por E?ou ?, dependendo de ter sido codificado usando um acento combinado ou um caractere pré-composto.

echo café äëïöü | tr -d '\200-\277' | tr '\300-\377' '[?*]'

Esse exemplo retorna caf? ?????, usando caracteres pré-compostos.

yellowantphil
fonte
trnão deve funcionar um byte de cada vez. GNU tr sim, mas é um bug.
Stéphane Chazelas
3
iconv -f utf-8 -t ascii//TRANSLITfuncionou bem para mim. Ele mudou aspas onduladas para aspas retas. Obrigado.
Coronel Panic
Observe que o iconv engasgará com caracteres acentuadamente acentuados, como Pinyin.
sventechie
Observe que //TRANSLITtambém funciona para outros conjuntos de caracteres, por exemplo iso-8859-1//TRANSLIT.
Skippy le Grand Gourou
iconvfornece iconv: illegal input sequence at position 1234e trunca o arquivo para mim. Seria bom se ele apenas deletasse o personagem e tentasse pegar a sequência novamente.
21418 johcqqk
3

experimentar uni2ascii -B input.txt >output.txt

uni2ascii

philcolbourn
fonte
2

Eu tenho um arquivo em UTF-8 que contém [nomes de pessoas] em vários idiomas [que desejo converter para algo significativo em ASCII].

Você quer dizer que deseja converter os seguintes nomes em alguma string ASCII que a pessoa em questão não se oporia?

  • ஸ்றீனிவாஸ ராமானுஜன் ஐயங்கார்
  • عبد الله الثاني بن الحسين

Eu suspeito que não há ferramenta automatizada que possa fazer isso. Pode haver uma ou muitas latinizações de nomes pessoais. O software não pode escolher a versão culturalmente aceitável. Pelo menos não sem o software saber muito sobre a cultura da pessoa envolvida.

Consulte também /programming//a/1398403/477035

RedGrittyBrick
fonte
2
perl -e 'use utf8; use Text::Unidecode; print unidecode("عبد الله الثاني بسين")'produz `` bd llh lthny bn lHsyn`, que é transliteração suficiente para meus propósitos.
User7610
4
@ user7610: Ótimo, mas o rei Abdulla II da Jordânia pode discordar. Eu iria preparar uma explicação no caso de alguém importante reclama com o CEO :-)
RedGrittyBrick
2

Acabei usando Perl com Text :: Unidecode para isso. Exemplo:

perl -e 'use utf8; use Text::Unidecode; print unidecode("عبد الله الثاني بسين")

produz bd llh lthny bn lHsyn, que é um resultado aceitável para meus propósitos.

user7610
fonte