Melhor maneira de converter arquivos de texto entre conjuntos de caracteres?

526

Qual é a ferramenta ou o método mais rápido e fácil para converter arquivos de texto entre conjuntos de caracteres?

Especificamente, preciso converter de UTF-8 para ISO-8859-15 e vice-versa.

Tudo funciona: one-liners na sua linguagem de script favorita, ferramentas de linha de comando ou outros utilitários para SO, sites da Web etc.

Melhores soluções até agora:

No Linux / UNIX / OS X / cygwin:

  • O gnu iconv sugerido por Troels Arvin é melhor usado como filtro . Parece estar universalmente disponível. Exemplo:

    $ iconv -f UTF-8 -t ISO-8859-15 in.txt > out.txt
    

    Como apontado por Ben , há um conversor online usando o iconv .

  • A recodificação de Gnu ( manual ) sugerida pela Cheekysoft converterá um ou vários arquivos no local . Exemplo:

    $ recode UTF8..ISO-8859-15 in.txt
    

    Este usa aliases mais curtos:

    $ recode utf8..l9 in.txt
    

    O Recode também suporta superfícies que podem ser usadas para converter entre diferentes tipos de final de linha e codificações:

    Converta novas linhas de LF (Unix) para CR-LF (DOS):

    $ recode ../CR-LF in.txt
    

    Arquivo de codificação Base64:

    $ recode ../Base64 in.txt
    

    Você também pode combiná-los.

    Converta um arquivo UTF8 codificado em Base64 com finais de linha Unix em arquivo Latin 1 codificado em Base64 com finais de linha Dos:

    $ recode utf8/Base64..l1/CR-LF/Base64 file.txt
    

No Windows com Powershell ( Jay Bazuzi ):

  • PS C:\> gc -en utf8 in.txt | Out-File -en ascii out.txt

    (No entanto, não há suporte ISO-8859-15; ele diz que os conjuntos de caracteres suportados são unicode, utf7, utf8, utf32, ascii, bigendianunicode, padrão e oem.)

Editar

Você quer dizer suporte iso-8859-1? O uso de "String" faz isso, por exemplo, vice-versa

gc -en string in.txt | Out-File -en utf8 out.txt

Nota: Os possíveis valores de enumeração são "Desconhecido, String, Unicode, Byte, BigEndianUnicode, UTF8, UTF7, Ascii".

Antti Sykäri
fonte
Eu tentei, gc -en Ascii readme.html | Out-File -en UTF8 readme.htmlmas ele converte o arquivo para utf-8, mas então está vazio! O Notepad ++ diz que o arquivo é no formato Ansi, mas a leitura que eu entendo não é mesmo um conjunto de caracteres válido? uk.answers.yahoo.com/question/index?qid=20100927014115AAiRExF
OZZIE
2
Basta encontrar uma resposta para uma pergunta relacionada - ótimo resumo! Apenas pensei que era pena acrescentar que recodeirá funcionar como um filtro, bem como se você não passar quaisquer nomes de arquivos, por exemplo:recode utf8..l9 < in.txt > out.txt
Jez
iconv.com/iconv.htm parece estar morto para mim? (Timeout)
Andrew Newby
2
Se você usar enca, não precisará especificar a codificação de entrada. Muitas vezes, é suficiente apenas para especificar o idioma: enca -L ru -x utf8 FILE.TXT.
Alexander Pozdneev
1
Na verdade, o iconv funcionou muito melhor como um conversor local, em vez de um filtro. A conversão de um arquivo com mais de 2 milhões de linhas usando iconv -f UTF-32 -t UTF-8 input.csv > output.csvapenas 770 mil linhas salvas, apenas um terço. O uso da versão local iconv -f UTF-32 -t UTF-8 file.csvconverteu com êxito todos os mais de 2 milhões de linhas.
Nicolay77

Respostas:

246

Abordagem de utilitário independente

iconv -f ISO-8859-1 -t UTF-8 in.txt > out.txt
-f ENCODING  the encoding of the input
-t ENCODING  the encoding of the output

Você não precisa especificar nenhum desses argumentos. Eles usarão como padrão o código de idioma atual, que geralmente é UTF-8.

Troels Arvin
fonte
4
Para quem está sendo enganado pelas versões sem traço, não está disponível, parece que as versões OSX (e possivelmente todas as BSD) do iconv não suportam os aliases sem traço para as várias codificações UTF- *. iconv -l | grep UTFmostrará todas as codificações relacionadas a UTF que sua cópia do iconv suporta.
Coredumperror
14
Não sabe a codificação do seu arquivo de entrada? Use chardet in.txtpara gerar uma melhor estimativa. O resultado pode ser usado como ENCODING in iconv -f ENCODING.
Guisado
4
Impedir a saída em caracteres inválidos (evitando illegal input sequence at positionmensagens), e substituir caracteres "estranhos" com personagens "semelhantes": iconv -c -f UTF-8 -t ISO-8859-1//TRANSLIT in.txt > out.txt.
knb
Eu gosto disso porque é padrão na maioria das plataformas NIX. Mas também ver a opção de comando VIM (apelido: ex) abaixo . Informações adicionais: (1) você (provavelmente) não precisa especificar a -fopção (de) com iconv. (2) o file --mime-encoding <file/s>comando pode ajudá-lo a descobrir a codificação em primeiro lugar.
fr13d
1
FWIW, o filecomando relatou minha fonte como UTF-16 Little Endian; executando iconv -f UTF-16 -t UTF-8...transformou-o incorretamente para ASCII, eu tive que especificar explicitamente iconv -f UTF-16LE...a saída UTF-8 #
1414 Platão
90

Experimente o VIM

Se você tiver, vimpode usar isto:

Não testado para todas as codificações.

A parte legal disso é que você não precisa saber a codificação da fonte

vim +"set nobomb | set fenc=utf8 | x" filename.txt

Esteja ciente de que este comando modifica diretamente o arquivo


Parte de explicação!

  1. +: Usado pelo vim para inserir diretamente o comando ao abrir um arquivo. Geralmente usado para abrir um arquivo em uma linha específica:vim +14 file.txt
  2. |: Separador de vários comandos (como ;no bash)
  3. set nobomb : nenhuma lista técnica utf-8
  4. set fenc=utf8: Defina a nova codificação como link de documento utf-8
  5. x : Salvar e fechar arquivo
  6. filename.txt : caminho para o arquivo
  7. ": qotes estão aqui por causa de tubos. (caso contrário, o bash os usará como pipe do bash)
Boop
fonte
Muito legal, mas um pouco lento. Existe uma maneira de mudar isso para converter vários arquivos de uma só vez (economizando nos custos de inicialização do vim)?
DomQ
Obrigado pela explicação! Eu estava tendo dificuldades com o início do arquivo até ler sobre a configuração de bomba / nobomb.
Jjwdesign # 03/16
1
np, additionaly você pode ver o bom se você usar vim -bouhead file.txt|cat -e
Boop
1
por exemplo:find -regextype posix-extended -type f -regex ".*\.(h|cpp|rc|fx|cs|props|xaml)" -exec vim +'set nobomb | set fenc=utf8 | x' {} \;
Gabriel
Eu usei isso para converter a codificação de arquivos CSV e fiquei muito empolgado quando vi que o charset havia realmente mudado. Infelizmente, quando fui carregar o arquivo no MySQL, ele tinha um número diferente de colunas do que o que tinha anteriormente antes de executar o comando vim. Gostaria de saber se seria possível simplesmente abrir o arquivo, converter a codificação e salvar / fechar o arquivo, deixando todo o conteúdo do mesmo arquivo?
NightOwlPrgmr
39

No Linux, você pode usar o poderoso comando recode para tentar converter entre os diferentes conjuntos de caracteres, bem como quaisquer problemas de final de linha. recode -l mostrará todos os formatos e codificações que a ferramenta pode converter. É provável que seja uma lista MUITO longa.

Cheekysoft
fonte
Como você se converte LF? Existe /CRe /CR-LFnão existe/LF
Aaron Franke
21

iconv (1)

iconv -f FROM-ENCODING -t TO-ENCODING file.txt

Também existem ferramentas baseadas em iconv em vários idiomas.

Daniel Papasian
fonte
1
Que tal detectar automaticamente a codificação original?
Aaron Franke
20
Get-Content -Encoding UTF8 FILE-UTF8.TXT | Out-File -Encoding UTF7 FILE-UTF7.TXT

A versão mais curta, se você puder assumir que a BOM de entrada está correta:

gc FILE.TXT | Out-File -en utf7 file-utf7.txt
Jay Bazuzi
fonte
1
Aqui está uma versão mais curta que funciona melhor. gc .\file-utf8.txt | sc -en utf7 .\file-utf7.txt
Larry Battle
@ LarryBattle: Como Set-Contentfunciona melhor do que Out-File?
Jay Bazuzi 15/07
... ah. Eu acho que eles são quase a mesma coisa. Ocorreu um problema ao executar o seu exemplo, porque estava assumindo que as duas versões estavam usando o mesmo file-utf8.txtarquivo para entrada, pois ambas tinham o mesmo arquivo de saída file-utf7.txt.
Larry Battle
Isso seria realmente ótimo, exceto que ele não suporta UTF16. Ele suporta UTF32, mas não UTF16! Eu não precisaria converter arquivos, exceto que muitos softwares da Microsoft (por exemplo, servidor SQL Server bcp) insistem no UTF16 - e seu utilitário não será convertido nele. Interessante para dizer o mínimo.
Noé
Eu tentei, gc -en Ascii readme.html | Out-File -en UTF8 readme.htmlmas ele converte o arquivo para utf-8, mas então está vazio! O Notepad ++ diz que o arquivo é no formato Ansi, mas a leitura que eu entendo não é mesmo um conjunto de caracteres válido? uk.answers.yahoo.com/question/index?qid=20100927014115AAiRExF
OZZIE
16

Experimente a função iconv Bash

Eu coloquei isso em .bashrc:

utf8()
{
    iconv -f ISO-8859-1 -t UTF-8 $1 > $1.tmp
    rm $1
    mv $1.tmp $1
}

..para poder converter arquivos assim:

utf8 MyClass.java
Arne Evertsson
fonte
8
é melhor usar tmp = $ (mktmp) para criar um arquivo temporário. Além disso, a linha com rm é redundante.
LMZ
1
você pode concluir esta função com o formato de entrada de detecção automática?
mlibre
3
cuidado, esta função exclui o arquivo de entrada sem verificar se a chamada iconv foi bem-sucedida.
philwalk
Isso altera o conteúdo do arquivo de texto. Eu executei isso em um UTF-8 com a BOM esperando obter um UTF-8 sem arquivo da BOM, mas ele foi anexado no início do arquivo.
Aaron Franke
14

Experimente o Notepad ++

No Windows, pude usar o Notepad ++ para fazer a conversão de ISO-8859-1 para UTF-8 . Clique "Encoding"e depois "Convert to UTF-8".

Jeremy Glover
fonte
13

Oneliner usando find, com detecção automática de conjunto de caracteres

A codificação de caracteres de todos os arquivos de texto correspondentes é detectada automaticamente e todos os arquivos de texto correspondentes são convertidos em utf-8codificação:

$ find . -type f -iname *.txt -exec sh -c 'iconv -f $(file -bi "$1" |sed -e "s/.*[ ]charset=//") -t utf-8 -o converted "$1" && mv converted "$1"' -- {} \;

Para executar essas etapas, um sub shell shé usado -exec, executando uma linha com o -csinalizador e passando o nome do arquivo como argumento posicional "$1"com -- {}. Nesse meio tempo, o utf-8arquivo de saída é nomeado temporariamente converted.

Pelo que file -bisignifica:

  • -b, --brief Não adicione nomes de arquivos às linhas de saída (modo breve).

  • -i, --mime Faz com que o comando file produza seqüências de caracteres do tipo MIME, em vez das legíveis por humanos mais tradicionais. Assim, pode dizer, por exemplo, text/plain; charset=us-asciie não ASCII text. O sedcomando corta isso para apenas us-asciiconforme exigido por iconv.

O findcomando é muito útil para essa automação de gerenciamento de arquivos. Clique aqui para mais findgalore .

Serge Stroobandt
fonte
3
Eu tive que adaptar um pouco essa solução para trabalhar no Mac OS X, pelo menos na minha versão. find . -type f -iname *.txt -exec sh -c 'iconv -f $(file -b --mime-encoding "$1" | awk "{print toupper(\$0)}") -t UTF-8 > converted "$1" && mv converted "$1"' -- {} \;
Brian J. Miller
1
Seu código também funcionou no Windows 7 com MinGW-w64 (versão mais recente). Obrigado por compartilhar!
silvioprog
@rmuller O sedcomando existe de propósito, permitindo a detecção automática da codificação de caracteres. Eu ampliei a resposta para explicar isso agora. Seria cortês com relação aos leitores excluir quaisquer comentários irrelevantes restantes. Obrigado.
Serge Stroobandt
@SergeStroobandt Talvez eu não tenha sido suficientemente claro. O que quero dizer é que quando você usa "arquivo -b - codificação de mímica" em vez de "arquivo -bi", não há necessidade de filtrar o resultado com o sed. Este comando já retorna apenas a codificação do arquivo. Assim, no seu exemplo "us-ascii"
rmuller
Isso realmente não parece fazer nada por mim no Linux. Salvei um arquivo como UTF-8 com BOM e esperava que ele fosse convertido em UTF-8 sem BOM e isso não aconteceu.
Aaron Franke
3

PHP iconv ()

iconv("UTF-8", "ISO-8859-15", $input);

user15096
fonte
1
Essa declaração funciona muito bem ao converter seqüências de caracteres, mas não para arquivos.
Jjwdesign # 03/16
2

DOS / Windows: use a página de códigos

chcp 65001>NUL
type ascii.txt > unicode.txt

O comando chcppode ser usado para alterar a página de código. Página de códigos 65001 é o nome da Microsoft para UTF-8. Após definir a página de códigos, a saída gerada pelos seguintes comandos será do conjunto de páginas de códigos.

lalthomas
fonte
1

para escrever o arquivo de propriedades (Java) normalmente eu uso isso no linux (distribuições mint e ubuntu):

$ native2ascii filename.properties

Por exemplo:

$ cat test.properties 
first=Execução número um
second=Execução número dois

$ native2ascii test.properties 
first=Execu\u00e7\u00e3o n\u00famero um
second=Execu\u00e7\u00e3o n\u00famero dois

PS: Escrevi a Execução número um / dois em português para forçar caracteres especiais.

No meu caso, na primeira execução, recebi esta mensagem:

$ native2ascii teste.txt 
The program 'native2ascii' can be found in the following packages:
 * gcj-5-jdk
 * openjdk-8-jdk-headless
 * gcj-4.8-jdk
 * gcj-4.9-jdk
Try: sudo apt install <selected package>

Quando instalei a primeira opção (gcj-5-jdk), o problema estava concluído.

Espero que isso ajude alguém.

Maciel Bombonato
fonte
0

Minha ferramenta favorita para isso é o Jedit (um editor de texto baseado em java), que possui dois recursos muito convenientes:

  • Um que permite ao usuário recarregar um texto com uma codificação diferente (e, como tal, controlar visualmente o resultado)
  • Outro que permite ao usuário escolher explicitamente a codificação (e o final da linha) antes de salvar
yota
fonte
0

Simplesmente altere a codificação do arquivo carregado no IntelliJ IDEA IDE, à direita da barra de status (inferior), onde o conjunto de caracteres atual é indicado. Solicita recarregar ou converter, use Converter. Faça backup do arquivo original com antecedência.

Nikolai Varankine
fonte
0

Se os aplicativos da interface do usuário do macOS são a sua cara , o SubEthaEdit é o editor de texto para o qual eu costumo ir para a codificação-disputa - sua "visualização de conversão" permite que você veja todos os caracteres inválidos na codificação de saída e corrija / remova-os.

E é de código aberto agora, então sim para eles 😉.

tiennou
fonte