Convertir un archivo UTF-8 a ASCII (mejor esfuerzo)

23

Tengo un archivo en UTF-8 que contiene textos en varios idiomas. Muchos de ellos son nombres de personas. Necesito convertirlo a ASCII y necesito que el resultado se vea lo más decente posible.

Hay muchas formas de abordar la conversión de una codificación más amplia a una más estrecha. La transformación más simple sería reemplazar todos los caracteres que no son ASCII con algún marcador de posición, como '_'. Si conozco el idioma en el que está escrito el archivo, hay posibilidades adicionales, como la romanización.

¿Qué herramienta de Unix o biblioteca de lenguaje de programación disponible en Unix me puede dar una conversión decente (el mejor esfuerzo) de UTF-8 a ASCII?

La mayor parte del texto está en idiomas europeos basados ​​en el tipo latino.

user7610
fuente
1
¿Sabes dónde comienza el idioma? Hay, por ejemplo, una diferencia sobre cómo manejar la no disponibilidad de una diéresis (como en el ö). En alemán siempre se puede escribir "oe", pero, por ejemplo, en holandés, la indisponibilidad de una diéresis se puede "describir" mejor con un guión seguido del carácter de diéresis (y allí la "oe" sería un diptongo completamente diferente)
Anthon
¿Cómo define "lo más decente posible"? La verdadera dificultad está en definir las asignaciones. En comparación con eso, la tarea de programación es trivial. Las asignaciones realmente utilizadas varían mucho y pueden ser específicas del idioma de dos maneras: dependen del idioma del texto y del idioma asumido por el lector (especialmente en lo que respecta a la romanización).
Jukka K. Korpela
@ JukkaK.Korpela "lo más decente posible", por supuesto, está definido por aquellos que crearon la "herramienta Unix o biblioteca de lenguaje de programación disponible en Unix" que estoy pidiendo. Si lo mejor que obtendré es reemplazar todo lo que no sea ASCII con un guión bajo, entonces no hay mucho más que pueda hacer. Excepto escribir mi propia herramienta, que no lo haré. Supongo que Unix @ SO podría no ser el mejor lugar para esta pregunta ...
user7610
1
@ user7610 Aparte de iconvy tr, hay Unidecode . No estoy familiarizado con él, pero podría hacer lo que quiera, si puede usar Python.
yellowantphil
1
@yellowantphil o node-unidecode en JavaScript / node, UnidecodeSharp en C♯ o Text :: Unidecode en Perl, que es el primero de este nombre. Supongo que hay otras versiones.
user7610

Respuestas:

11
konwert utf8-ascii

Hará la conversión de mejor esfuerzo, dependiendo de las tablas de conversión. Si conoce aproximadamente el idioma de entrada, hay filtros específicos de idioma que ofrecen mejores resultados, por ejemplo

konwert utf8-xmetodo

es la conversión del esperanto en la representación x-metodo,

konwert UTF8-tex

intentará hacer una representación TeX de diacríticos, hay parámetros específicos del idioma:

konwert UTF8-ascii/de

transliterará "ä" en "ae" (habitual para el alemán) en lugar de "a"

konwert UTF8-ascii/rosyjski

utilizará las reglas polacas para transcribir el ruso, en lugar de las "inglesas", etc.

Radovan Garabík
fuente
¿Es esta la última ubicación del konwertsitio web? ¿Está empaquetado en alguna parte? github.com/taw/konwert/tree/master/konwert-1.8
Nemo
25

Esto funcionará para algunas cosas:

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

echo ĥéĺłœ π | iconv -f utf-8 -t ascii//TRANSLITvuelve helloe ?. Cualquier carácter que iconvno sepa cómo convertir será reemplazado por signos de interrogación.

iconves POSIX, pero no sé si todos los sistemas tienen la TRANSLITopción. A mí me funciona en Linux. Además, la IGNOREopción descartará silenciosamente los caracteres que no se pueden representar en el conjunto de caracteres de destino (ver man iconv_open).

Una opción inferior pero compatible con POSIX es usar tr. Este comando reemplaza todos los puntos de código que no son ASCII con un signo de interrogación. Lee el texto UTF-8 un byte a la vez. "É" podría reemplazarse con E?o ?, dependiendo de si se codificó utilizando un acento combinado o un carácter precompuesto.

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

Ese ejemplo regresa caf? ?????, usando caracteres precompuestos.

yellowantphil
fuente
trno está destinado a trabajar un byte a la vez. GNU tr lo hace, pero es un error.
Stéphane Chazelas
3
iconv -f utf-8 -t ascii//TRANSLITfuncionó bien para mí Cambió las comillas rizadas por comillas rectas. Gracias.
Coronel Panic
Tenga en cuenta que iconv se ahogará con caracteres muy acentuados como Pinyin.
sventechie
Tenga en cuenta que //TRANSLITtambién funciona para otros conjuntos de caracteres, por ejemplo iso-8859-1//TRANSLIT.
Skippy le Grand Gourou
iconvda iconv: illegal input sequence at position 1234y trunca el archivo por mí. Sería bueno si simplemente eliminara el personaje e intentara retomar la secuencia nuevamente.
jozxyqk
3

tratar uni2ascii -B input.txt >output.txt

uni2ascii

philcolbourn
fuente
2

Tengo un archivo en UTF-8 que contiene [nombres de personas] en varios idiomas [que quiero convertir en algo significativo en ASCII].

¿Quiere decir que desea poder convertir los siguientes nombres en una cadena ASCII a la que la persona interesada no se opondría?

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

Sospecho que no hay una herramienta automatizada que pueda hacer esto. No puede haber ninguna o muchas latinizaciones de nombres personales. El software no puede elegir la versión culturalmente aceptable. Al menos no sin que el software sepa mucho sobre la cultura de la persona involucrada.

Ver también /programming//a/1398403/477035

RedGrittyBrick
fuente
2
perl -e 'use utf8; use Text::Unidecode; print unidecode("عبد الله الثاني بسين")'produce `` bd llh lthny bn lHsyn` que es una transcripción lo suficientemente buena para mis propósitos.
user7610
44
@ user7610: Bien, pero el Rey Abdulla II de Jordania podría estar en desacuerdo. Prepararía una explicación en caso de que alguien importante se queje al CEO :-)
RedGrittyBrick
2

Terminé usando Perl con Text :: Unidecode para esto. Ejemplo:

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

produce bd llh lthny bn lHsyn, que es un resultado aceptable para mis propósitos.

user7610
fuente