Como determino a codificação de arquivo no OS X?

171

Estou tentando inserir alguns caracteres UTF-8 em um arquivo LaTeX no TextMate (que diz que sua codificação padrão é UTF-8), mas o LaTeX parece não entendê-los.

A execução cat my_file.texmostra os caracteres corretamente no Terminal. A execução ls -almostra algo que eu nunca vi antes: um "@" na lista de arquivos:

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

(E, sim, estou usando \usepackage[utf8]{inputenc}no LaTeX.)

Eu descobri iconv, mas isso não parece ser capaz de me dizer qual é a codificação - ela só será convertida quando eu descobrir.

James A. Rosen
fonte
Na minha experiência, o comando file (1) sempre foi muito bom em adivinhar a codificação de um arquivo. Não sei se é inteligente o suficiente para usar o atributo estendido com.apple.TextEncoding do arquivo ou não.
Edward Falk

Respostas:

33

O @meio que o arquivo estendeu atributos de arquivo associados a ele. Você pode consultá-los usando a getxattr()função

Não há uma maneira definida de detectar a codificação de um arquivo. Leia esta resposta, explica o porquê.

Existe uma ferramenta de linha de comando, enca , que tenta adivinhar a codificação. Você pode querer dar uma olhada.

codelogic
fonte
1
Eu estava assumindo que o OSX armazenava a codificação como metadados. Entendi que o conteúdo do arquivo era apenas um cluster de bits e não tinha codificação inerente.
12339 James A. Rosen
1
Os aplicativos JamesA.Rosen do OS X, como o TextEdit, armazenam a codificação de arquivo como um atributo (chamado "com.apple.TextEncoding"). É bem provável que os atributos indicados por isso @incluam o atributo de codificação de arquivo. Você pode usar o comando xattr -p com.apple.TextEncoding <filename>para examinar o atributo de codificação, se existir.
bames53
1
você pode explicar como usar o getxattr? Eu não sou capaz de usá-lo.
MeV
1
Essa é uma chamada de função que você usaria se quiser escrever um programa. Na linha de comando, digite apenas ls -l@ <filename>para ver quais atributos estão definidos para o arquivo. Para ver o atributo real, digitexattr -p com.apple.TextEncoding <filename>
Edward Falk
Para conseguir encafazer brew install encae você tem que especificar a língua, mas nenhum funciona, então:enca FILENAME -L __
Shane
434

Usar a opção -I(que é um i maiúsculo) no comando file parece mostrar a codificação do arquivo.

file -I {filename}
Tim
fonte
58
Eu precisava usar -I
Casebash
7
Esta função parecia ser incapaz de dizer a diferença entre ASCII e UTF-8 (Parece que eles são os mesmos para a maioria dos personagens norte-americanos, mas não todos, talvez algo que pudesse detectar o bit unicode)
BadPirate
14
ASCII e UTF8 são os mesmos, a menos que exista um caractere além do OxFF no arquivo ou uma BOM.
Davidtbernal
3
file -I *parece funcionar perfeitamente para mim (no OSX). Um sistema reclamou da codificação de um dos muitos arquivos, sem especificar quais. Todos os arquivos eram ascii, exceto um, que era utf-8. Provavelmente o culpado.
Mcv #
1
@notJim Isso está incorreto. ASCII é definido apenas através de 0x7F, portanto, qualquer coisa além desse ponto não é claramente ASCII. Unicode e Latin-1 têm os mesmos pontos de código em 0x80-0xFF, mas não há codificação comum de Unicode que seja idêntica a Latin-1 (porque isso seria inerentemente restrito a 8 bits, o que é muito pouco para Unicode).
Tripleee
56

No Mac OS X, o comando file -I(capital i) fornecerá o conjunto de caracteres adequado, desde que o arquivo que você está testando contenha caracteres fora do intervalo ASCII básico.

Por exemplo, se você for ao Terminal e usar o vi para criar um arquivo, por exemplo. vi test.txt em seguida, insira alguns caracteres e inclua um caractere acentuado (tente ALT-e seguido por e) e salve o arquivo.

Eles digitam file -I text.txte você deve obter um resultado como este:

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

Cloudranger
fonte
3
Posso confirmar o caso do OS X, charset = us-ascii ou charset = utf-8, dependendo do conteúdo do arquivo
Ben Ben
mas parece apenas observar os primeiros KB do arquivo. no meu caso, o comando vim em stackoverflow.com/a/33644535/161022 identificou corretamente o arquivo como utf-8, enquanto o filecomando reivindica seuus-ascii
lmsurprenant
De fato, parece que o arquivo trapaceia por razões de desempenho. Acabei de criar um arquivo ASCII de 3 MB no Ubuntu e adicionei alguns caracteres UTF-8 ao final, e ele ainda relata ASCII e não UTF-8. Eu tentei a opção -k (continue), mas depois ele relata "dados" e não "UTF-8", por isso ainda não é bom.
Cloudranger 8/04
24
vim -c 'execute "silent !echo " . &fileencoding | q' {filename}

alias em algum lugar da minha configuração do bash como

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

então eu apenas digito

vic {filename}

No meu OSX Yosemite de baunilha, ele produz resultados mais precisos que o "arquivo -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
fonte
1
Esta é a única resposta que me deu o que eu precisava - "latin1", em oposição a "us-ascii". Embora eu tenha que remover as barras invertidas.
precisa saber é o seguinte
Muito obrigado, removi as barras invertidas.
precisa saber é o seguinte
21

Você também pode converter de um tipo de arquivo para outro usando o seguinte comando:

iconv -f original_charset -t new_charset originalfile > newfile

por exemplo

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

Apenas use:

file -I <filename>

É isso aí.

bx2
fonte
2
Não posso me incomodar em votar, mas essa resposta está completamente errada. Small -i diz que não classifica o conteúdo se for um arquivo regular. -I é equivalente a --mime, que gera seqüências do tipo mime. As ferramentas osx se comportam de maneira diferente das ferramentas linux padrão.
sillyMunky
Bem, para um arquivo codificado no Windows 1252 file -Ime entende text/plain; charset=unknown-8bit. Embora ele funciona melhor para um arquivo UTF-8: text/plain; charset=utf-8.
MiB
8

Usar o filecomando com a --mime-encodingopção (por exemplo file --mime-encoding some_file.txt) em vez da opção -I funciona no OS X e tem o benefício adicional de omitir o tipo mime, "text / plain", com o qual você provavelmente não se importa.

Adão
fonte
ls -l @ a mostrará atributos estendidos . Olhando a página de manual para ls no Yosemite, não vejo uma opção de codificação --mime.
Rtackhouse
Você estava falando sobre o filecomando. Não sabia que existia. Novato. De qualquer forma. Desculpe pelo voto negativo. SO não me permitirá desfazer a menos que alguém edite esta resposta.
Rtackhouse
4

O LaTeX clássico de 8 bits é muito restrito em quais caracteres UTF8 ele pode usar; é altamente dependente da codificação da fonte que você está usando e dos glifos disponíveis.

Como você não fornece um exemplo específico, é difícil saber exatamente onde está o problema - se você está tentando usar um glifo que sua fonte não possui ou se não está usando a codificação de fonte correta no primeiro Lugar, colocar.

Aqui está um exemplo mínimo, mostrando como alguns caracteres UTF8 podem ser usados ​​em um documento LaTeX:

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

Você pode ter mais sorte com a codificação [utf8x], mas esteja um pouco avisado de que ela não é mais suportada e tem algumas idiossincrasias em comparação com a [utf8] (tanto quanto me lembro; já faz um tempo desde que a observei). Mas se der certo, é tudo o que importa para você.

Will Robertson
fonte
3

O sinal @ significa que o arquivo possui atributos estendidos . xattr filemostra quais atributos ele possui, xattr -l filemostra também os valores dos atributos (que às vezes podem ser grandes - tente, por exemplo, xattr /System/Library/Fonts/HelveLTMMver uma fonte de estilo antigo existente na bifurcação de recursos).

Jouni K. Seppänen
fonte
2

Digitar file myfile.texem um terminal pode às vezes indicar a codificação e o tipo de arquivo usando uma série de algoritmos e números mágicos. É bastante útil, mas não conte com o fornecimento de informações concretas ou confiáveis.

Um Localizable.stringsarquivo (encontrado em aplicativos Mac OS X localizados) geralmente é relatado como um arquivo de origem UTF-16 C.

dreamlax
fonte
1

Synalyze It! permite comparar texto ou bytes em todas as codificações que a biblioteca ICU oferece. Usando esse recurso, você geralmente vê imediatamente qual página de código faz sentido para seus dados.

pi3
fonte
1

Você pode tentar carregar o arquivo em uma janela do firefox e ir para Exibir - Codificação de caracteres. Deve haver uma marca de seleção ao lado do tipo de codificação do arquivo.

jmdeamer
fonte
0

Qual LaTeX você está usando? Quando estava usando o teTeX, tive que baixar manualmente o pacote unicode e adicioná-lo aos meus arquivos .tex:

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

Agora, mudei para o XeTeX a partir do pacote TeXlive 2008 ( aqui ), é ainda mais simples:

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

Quanto à detecção da codificação de um arquivo, você pode brincar file(1)(mas é bastante limitado), mas, como alguém disse, é difícil.

Keltia
fonte
0

Uma maneira de força bruta para verificar a codificação pode ser apenas verificar o arquivo em um editor hexadecimal ou similar. (ou escreva um programa para verificar) Veja os dados binários no arquivo. O formato UTF-8 é bastante fácil de reconhecer. Todos os caracteres ASCII são bytes únicos com valores abaixo de 128 (0x80) sequências de vários bytes seguem o padrão mostrado no artigo da wiki

Se você puder encontrar uma maneira mais simples de obter um programa para verificar a codificação para você, isso é obviamente um atalho, mas se tudo mais falhar, isso funcionaria.

jalf
fonte
0

Eu implementei o script bash abaixo, ele funciona para mim.

Ele primeiro tenta a iconvpartir da codificação retornada por file --mime-encodingpara utf-8.

Se isso falhar, ele passa por todas as codificações e mostra a diferença entre o arquivo original e o recodificado. Ele pula as codificações que produzem uma saída diferencial grande ("grande", conforme definido pela MAX_DIFF_LINESvariável ou pelo segundo argumento de entrada), pois essas são provavelmente a codificação incorreta.

Se "coisas ruins" acontecerem como resultado do uso desse script, não me culpe. Tem um rm -flá, então tem monstros. Tentei evitar efeitos adversos usando-o em arquivos com sufixo aleatório, mas não estou fazendo nenhuma promessa.

Testado em 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
João Encarnação
fonte