¿Cómo determino la codificación de archivos en OS X?

171

Estoy tratando de ingresar algunos caracteres UTF-8 en un archivo LaTeX en TextMate (que dice que su codificación predeterminada es UTF-8), pero LaTeX no parece entenderlos.

La ejecución cat my_file.texmuestra los caracteres correctamente en la Terminal. La ejecución ls -almuestra algo que nunca había visto antes: una "@" en la lista de archivos:

-rw-r--r--@  1 me      users      2021 Feb 11 18:05 my_file.tex

(Y sí, lo estoy usando \usepackage[utf8]{inputenc}en LaTeX).

Lo he encontrado iconv, pero eso no parece ser capaz de decirme cuál es la codificación: solo se convertirá una vez que lo descubra.

James A. Rosen
fuente
En mi experiencia, el comando file (1) siempre ha sido bastante bueno para adivinar la codificación de un archivo. No sé si es lo suficientemente inteligente como para usar el atributo extendido com.apple.TextEncoding del archivo o no.
Edward Falk

Respuestas:

33

Los @medios de que el archivo tiene archivo extendido atributos asociados con él. Puedes consultarlos usando la getxattr()función.

No hay una forma definitiva de detectar la codificación de un archivo. Lea esta respuesta, explica por qué.

Hay una herramienta de línea de comandos, enca , que intenta adivinar la codificación. Quizás quieras revisarlo.

codelogic
fuente
1
Supuse que OSX almacenaba la codificación como metadatos. Comprendí que el contenido del archivo era solo un grupo de bits y no tenía codificación inherente.
James A. Rosen
1
@ JamesA.Rosen las aplicaciones de OS X como TextEdit almacenan la codificación de archivos como un atributo (llamado "com.apple.TextEncoding"). Es muy probable que los atributos indicados por eso @incluyan el atributo de codificación del archivo. Puede usar el comando xattr -p com.apple.TextEncoding <filename>para ver el atributo de codificación si existe.
bames53
1
¿Puedes explicar cómo usar getxattr? No puedo usarlo.
MeV
1
Esa es una llamada de función que usaría si desea escribir un programa. Desde la línea de comando, simplemente escriba ls -l@ <filename>para ver qué atributos están establecidos para el archivo. Para ver el atributo real, escribaxattr -p com.apple.TextEncoding <filename>
Edward Falk
Para encahacerlo brew install encay tienes que especificar el idioma pero ninguno funciona, entonces:enca FILENAME -L __
Shane
434

El uso de la -Iopción (que es una i mayúscula) en el comando de archivo parece mostrar la codificación del archivo.

file -I {filename}
Tim
fuente
58
Necesitaba usar -I
Casebash
77
Esta función parecía ser incapaz de distinguir entre ASCII y UTF-8 (parece que son iguales para la mayoría de los caracteres estadounidenses, pero no para todos, quizás algo que detecte el bit Unicode)
BadPirate
14
ASCII y UTF8 son iguales a menos que haya un carácter más allá de OxFF en el archivo o una lista de materiales.
davidtbernal
3
file -I *Parece funcionar perfectamente para mí (en OSX). Un sistema se quejó de la codificación de uno de los muchos archivos, sin especificar cuál. Todos los archivos eran ascii, excepto uno, que era utf-8. Lo más probable es el culpable.
mcv
1
@notJim Eso es incorrecto. ASCII solo se define a través de 0x7F, por lo que cualquier cosa más allá de ese punto claramente no es ASCII. Unicode y Latin-1 tienen los mismos puntos de código en 0x80-0xFF pero no hay una codificación común de Unicode que sea idéntica a Latin-1 (porque eso estaría inherentemente restringido a 8 bits, que es demasiado poco para Unicode).
tripleee
56

En Mac OS X, el comando file -I(mayúscula i) le dará el juego de caracteres adecuado siempre que el archivo que está probando contenga caracteres fuera del rango ASCII básico.

Por ejemplo, si vas a Terminal y usas vi para crear un archivo, por ejemplo. vi test.txt luego inserte algunos caracteres e incluya un carácter acentuado (intente ALT-e seguido de e) luego guarde el archivo.

Escriben file -I text.txty deberías obtener un resultado como este:

test.txt: text/plain; charset=utf-8

Cloudranger
fuente
3
Puedo confirmar el caso de OS X, charset = us-ascii o charset = utf-8 dependiendo del contenido del archivo
Ben
pero solo parece mirar los primeros KB del archivo. en mi caso, el comando vim en stackoverflow.com/a/33644535/161022 identificó correctamente el archivo como utf-8, mientras que el filecomando reclama suus-ascii
lmsurprenant
De hecho, parece que el archivo engaña por razones de rendimiento. Acabo de crear un archivo ASCII de 3MB en Ubuntu y agregué algunos caracteres UTF-8 hasta el final y aún informa ASCII no UTF-8. Intenté la opción -k (continuar) pero luego informa "datos" no "UTF-8", así que todavía no sirve.
Cloudranger
24
vim -c 'execute "silent !echo " . &fileencoding | q' {filename}

alias en algún lugar de mi configuración bash como

alias vic="vim -c 'execute \"silent !echo \" . &fileencoding | q'"

así que solo escribo

vic {filename}

En mi vanilla OSX Yosemite, produce resultados más precisos que "archivo -I":

$ file -I pdfs/udocument0.pdf
pdfs/udocument0.pdf: application/pdf; charset=binary
$ vic pdfs/udocument0.pdf
latin1
$
$ file -I pdfs/t0.pdf
pdfs/t0.pdf: application/pdf; charset=us-ascii
$ vic pdfs/t0.pdf
utf-8
jmettraux
fuente
1
Esta es la única respuesta que me dio lo que necesitaba: "latin1", en lugar de "us-ascii". Aunque, tuve que eliminar las barras invertidas.
Katy Lavallee
Muchas gracias, eliminé las barras invertidas.
jmettraux
21

También puede convertir de un tipo de archivo a otro con el siguiente comando:

iconv -f original_charset -t new_charset originalfile > newfile

p.ej

iconv -f utf-16le -t utf-8 file1.txt > file2.txt
RPM
fuente
13

Solo usa:

file -I <filename>

Eso es.

bx2
fuente
2
No puedo molestarme en votar, pero esa respuesta es completamente incorrecta. Pequeño -i dice que no clasifique el contenido si es un archivo normal. -I es equivalente a --mime que genera cadenas de tipo mime. Las herramientas osx se comportan de manera diferente a las herramientas linux estándar.
sillyMunky
Bueno, para un archivo codificado de Windows 1252 file -Ime atrapa text/plain; charset=unknown-8bit. A pesar de que funciona mejor para un archivo UTF-8: text/plain; charset=utf-8.
MiB
8

Usar el filecomando con la --mime-encodingopción (p file --mime-encoding some_file.txt. Ej. ) En lugar de la opción -I funciona en OS X y tiene el beneficio adicional de omitir el tipo mime, "text / plain", que probablemente no le interese.

Adán
fuente
ls -l @ a mostrará atributos extendidos . Al mirar la página de manual de ls en Yosemite, no veo una opción de codificación --mime.
rstackhouse
Estabas hablando del filecomando. No sabía que existía. Novato. De todas formas. Perdón por el voto negativo. SO no me deja deshacerlo a menos que alguien edite esta respuesta.
rstackhouse
4

El clásico LaTeX de 8 bits está muy restringido en los caracteres UTF8 que puede usar; depende en gran medida de la codificación de la fuente que esté utilizando y de los glifos que esa fuente tenga disponibles.

Como no da un ejemplo específico, es difícil saber exactamente dónde está el problema: si está intentando usar un glifo que su fuente no tiene o si no está usando la codificación de fuente correcta en el primer sitio.

Aquí hay un ejemplo mínimo que muestra cómo se pueden usar algunos caracteres UTF8 en un documento LaTeX:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[utf8]{inputenc}
\begin{document}
‘Héllø—thêrè.’
\end{document}

Es posible que tenga más suerte con la codificación [utf8x], pero tenga en cuenta que ya no es compatible y tiene algunas idiosincrasias en comparación con [utf8] (por lo que recuerdo; ha pasado un tiempo desde que lo vi). Pero si funciona, eso es todo lo que importa para ti.

Will Robertson
fuente
3

El signo @ significa que el archivo tiene atributos extendidos . xattr filemuestra qué atributos tiene, también xattr -l filemuestra los valores de los atributos (que a veces pueden ser grandes; intente, por ejemplo, xattr /System/Library/Fonts/HelveLTMMver una fuente antigua que exista en la bifurcación de recursos).

Jouni K. Seppänen
fuente
2

Escribir file myfile.texen un terminal a veces puede indicarle la codificación y el tipo de archivo utilizando una serie de algoritmos y números mágicos. Es bastante útil, pero no confíe en que proporcione información concreta o confiable.

Un Localizable.stringsarchivo (que se encuentra en aplicaciones localizadas de Mac OS X) generalmente se informa como un archivo fuente UTF-16 C.

dreamlax
fuente
1

Synalyze It! permite comparar texto o bytes en todas las codificaciones que ofrece la biblioteca ICU . Al usar esa función, generalmente ve de inmediato qué página de códigos tiene sentido para sus datos.

pi3
fuente
1

Puede intentar cargar el archivo en una ventana de Firefox y luego ir a Ver - Codificación de caracteres. Debe haber una marca de verificación junto al tipo de codificación del archivo.

jmdeamer
fuente
0

¿Qué LaTeX estás usando? Cuando estaba usando teTeX, tuve que descargar manualmente el paquete Unicode y agregar esto a mis archivos .tex:

% UTF-8 stuff
\usepackage[notipa]{ucs}
\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}

Ahora, me cambié a XeTeX desde el paquete TeXlive 2008 ( aquí ), es aún más simple:

% UTF-8 stuff
\usepackage{fontspec}
\usepackage{xunicode}

En cuanto a la detección de la codificación de un archivo, puedes jugar file(1)(pero es bastante limitado) pero, como dijo alguien más, es difícil.

Keltia
fuente
0

Una forma de fuerza bruta para verificar la codificación podría ser simplemente verificar el archivo en un editor hexadecimal o similar. (o escriba un programa para verificar) Mire los datos binarios en el archivo. El formato UTF-8 es bastante fácil de reconocer. Todos los caracteres ASCII son bytes individuales con valores inferiores a 128 (0x80) Las secuencias multibyte siguen el patrón que se muestra en el artículo wiki.

Si puede encontrar una manera más simple de obtener un programa para verificar la codificación por usted, obviamente es un acceso directo, pero si todo lo demás falla, esto sería el truco.

jalf
fuente
0

Implementé el script bash a continuación, funciona para mí.

Primero intenta iconvdesde la codificación devuelta por file --mime-encodingto utf-8.

Si eso falla, pasa por todas las codificaciones y muestra la diferencia entre el archivo original y el codificado nuevamente. Se salta las codificaciones que producen una gran salida de diferencia ("grande" según lo definido por la MAX_DIFF_LINESvariable o el segundo argumento de entrada), ya que es muy probable que la codificación sea incorrecta.

Si suceden "cosas malas" como resultado del uso de este script, no me culpe. Hay una rm -fallí, así que habrá monstruos. Traté de evitar efectos adversos al usarlo en archivos con un sufijo aleatorio, pero no estoy haciendo ninguna promesa.

Probado en Darwin 15.6.0.

#!/bin/bash

if [[ $# -lt 1 ]]
then
  echo "ERROR: need one input argument: file of which the enconding is to be detected."
  exit 3
fi

if [ ! -e "$1" ]
then
  echo "ERROR: cannot find file '$1'"
  exit 3
fi

if [[ $# -ge 2 ]]
then
  MAX_DIFF_LINES=$2
else
  MAX_DIFF_LINES=10
fi


#try the easy way
ENCOD=$(file --mime-encoding $1 | awk '{print $2}')
#check if this enconding is valid
iconv -f $ENCOD -t utf-8 $1 &> /dev/null
if [ $? -eq 0 ]
then
  echo $ENCOD
  exit 0
fi

#hard way, need the user to visually check the difference between the original and re-encoded files
for i in $(iconv -l | awk '{print $1}')
do
  SINK=$1.$i.$RANDOM
  iconv -f $i -t utf-8 $1 2> /dev/null > $SINK
  if [ $? -eq 0 ]
  then
    DIFF=$(diff $1 $SINK)
    if [ ! -z "$DIFF" ] && [ $(echo "$DIFF" | wc -l) -le $MAX_DIFF_LINES ]
    then
      echo "===== $i ====="
      echo "$DIFF"
      echo "Does that make sense [N/y]"
      read $ANSWER
      if [ "$ANSWER" == "y" ] || [ "$ANSWER" == "Y" ]
      then
        echo $i
        exit 0
      fi
    fi
  fi
  #clean up re-encoded file
  rm -f $SINK
done

echo "None of the encondings worked. You're stuck."
exit 3
Joao Encarnacao
fuente