[update]
Esse tópico recebeu uma versão atualizada. Embora esse aqui continue correto e completamente funcional. A versão atualizada contém mais informações e agrega o conteúdo gerado pelos comentários desse tópico até a data de publicação daquele tópico.
[/update]
O fato é que tive que fazer uma pesquisa sobre como converter um tipo de arquivo em outro. O que me impressionou não foi a dificuldade de achar uma solução, mas a complexidade de algumas soluções que eu encontrei. Pensei que certamente tal complexidade não seria necessária e estava certo !
Encontrei uma dica no rodapé do site das FunçõesZZ ensinando justamente como converter o arquivo das FunçõesZZ, que é escrito em ISO-8859-1, em UTF-8.
O comando é muito simples: iconv
Faz parte da libc6, ou seja, todo mundo têm instalado, e possuí sintaxe simples.
iconv -f codificacao_de_origem -t codificacao_de_saida arquivo
Assim para converter UTF-8 para ISO-8859-1 temos:
iconv -f utf-8 -t iso-8859-1 arquivo
Para o contrário utilizamos:
iconv -f iso-8859-1 -t utf-8 arquivo
É necessário redirecionar a saida de arquivo para algum lugar, algo como:
iconv -f utf-8 -t iso-8859-1 arquivo > novo_arquivo
Sendo assim, eu acrescentei ao meu ~/.bashrc* as seguintes linhas
alias iso2utf='iconv -f iso-8859-1 -t utf-8'
alias utf2iso='iconv -f utf-8 -t iso-8859-1'
Agora quando eu quiser converter um tipo de arquivo em outro, eu só preciso usar o iso2utf ou o utf2iso
Agora, por que tanta desinformação sobre assunto ? É tão fácil converter um tipo em outro, é tão simples !
[update]
O Marcelo Oliveira escreveu um belo script para fazer a conversão em lote e o colocou aqui, nos comentários.
O script apresenta o cuidado de não modificar seus arquivos originais, produzindo uma cópia dos mesmos em outros diretórios. Modificar o comportamento do script para converter arquivo iso-8859 para utf-8 é trivial (pelo menos para quem leu o tópico até aqui). Um detalhe importante é que o script não suporta caminhos ou nomes que contenham espaços (Posso estar enganado, mas o Marcelo deve ter utilizado esse script em um diretório de dados para internet onde espaços não são comuns e arquivos de imagem são.).
Marcelo, eu e a galera agradecemos a iniciativa e a colaboração!
[/update]
Tive o mesmo problema e resolvi da mesma maneira. Pena que ainda assim alguns acentos ficaram errados como o "É". Ainda estou trabakhando nisso... E assim achei seu blog! :)
ReplyDeletePois é, encontrei um programa chamado recode, apt-get install recode no Ubuntu. Só ficou errado agora o "É". Todo o resto está ok...
ReplyDelete"Agora, por que tanta desinformação sobre assunto ? É tão fácil converter um tipo em outro, é tão simples!"
ReplyDeleteEsta conversão é algo realmente simples e utilíssimo para quem tem problemas com acentuação, seja no HTML, seja em banco de dados MySQL quando faz migrações (como é o meu caso).
No entanto, mesmo sendo algo muito simples, o único site que fala sobre isto é este.
Apenas é necessário tomar cuidado no caso de caracteres especiais que dão erro na conversão utf2iso como alguns traços (os mais longos) ou algumas aspas especiais (francesas).
De fato, os caracteres que só existem em UTF-8 não são convertidos. Bem notado.
ReplyDelete[]'s
Pelo contexto, estou entendendo que a conversão é realizada no conteúo do arquivo texto. Ou se trata da conversão no nome do arquivo?
ReplyDeleteOoops!!!
ReplyDeleteDesculpe a demora.
Sim... o texto se refere apenas ao conteúdo do arquivo. Não ao nome.
Para modificar o nome, existem vários aplicativos prontos, mas se pode até usar o mesmo conceito dentro de um script.
Quando eu comecei a usar o iconv com mais freqüência, também defini "iso2utf" e "utf2iso" em meu bashrc, e ainda por cima com os mesmos nomes. O iconv é ótimo, mas ficar digitando esses parâmetros o tempo todo é um atraso de vida!
ReplyDeleteSão os nomes mais intuitivos do mundo...
ReplyDeleteO iso2utf tem problema de nao incluir o BOM ("Byte Order Mark") no ficheiro. O ficheiro em formato UTF deve comecar com bytes EFBB (hex). Alquem tem resolvido este?
ReplyDeleteTare
Se isso é um problema, nunca percebi qualquer erro ...
ReplyDeleteMas recentemente eu "li" gente dizendo que o iconv era ultrapassado. Pode até ser, mas ainda é o melhor. Se substituto, o recode, ainda apresenta erros.
[]'s
Obrigado pelas informações.
ReplyDeleteAjudarem muito a resolver meu problema, que era converter todos os arquivos de uma determinada pasta e subpastas de utf-8 para iso-8859-1.
Para isso escrevi um script que chamei de um nome super original: utf2iso.sh =)
segue abaixo o fonte.
-----
#!/bin/bash
# 04/07/2007
# por Marcelo Oliveira - www.iboletim.com.br
# Licença de uso: GPL
# uso:
# utf2iso.sh diretorio-a-ser-convertido
# fecha se nao for fornecido nenhum argumento
if [ $# -eq 0 ]
then
echo "ERRO: especifique o nome da pasta com os arquivos a serem convertidos!"
echo "Uso: ./utf2iso.sh diretorio-a-ser-convertido"
exit 1
fi
# cria diretorio para armazenar arquivos convertidos
cp -R $1 iso-8859-1
# acessa diretorio com os arquivos a serem convertidos
cd $1
# cria lista de todos os arquivos que serao convertidos (estou excluindo .gif e .jpg)
lista=`find -type f | grep -v gif | grep -v jpg`
# executa conversao
for i in $lista
do
echo "convertendo... $i"
iconv -f utf-8 -t iso-8859-1 $i > ../iso-8859-1/$i;
#read; # para verificar as mensagens de erro
done
if [ $? == 0 ]
then
echo -e "\nConversao terminada com sucesso!\n"
fi
-----
Boa, Marcelo,
ReplyDeletesua contribuição será, certamente, muito útil para muita gente.
Obrigado !
Como eu sei que tem gente que não lê até aqui, eu vou chamar a atenção para o script no corpo do tópico.
Abraços.
Mitre,
ReplyDeleteFico feliz em saber que será útil, assim com o seu post foi pra mim.
Realmente fiz esse script para converter um plugin do Joomla e não me preocupei com essa questão dos espaços...
Abraço.
Marcelo, sabe como eu tive o palpite da sua intenção ? Pela linha:
ReplyDeletefind -type f | grep -v gif | grep -v jpg
Que tipo de aplicação você converte o conteúdo recursivamente e exclui esses dois tipos de imagem ? Sites ...
Abraços !
Caro Mitre,
ReplyDeletePor estes dias andei baixando umas músicas no computador do meu irmão, ele é bitolado na porcaria do windows e as músicas estão com caracteres "ç é" e coisas do tipo.
Pesquisei aqui
e econtrei um script, além de ter testado as funões zz, acho que as mesmas carecem de uma função zziconv não acha?
Sérgio,
ReplyDeletevamos separar dois problemas aqui. O primeiro é o de codificação dos nomes, o segundo é o windows.
Há um problema com alguns nomes de arquivos vindos do windows que são irrecuperáveis. Eu não faço idéia do porque isso ocorre, mas que ocorre, ocorre.
Dito isso, voltamos ao script. Sim, alguma coisa nesse assunto. Mas falta, antes de tudo, um jeito de descobrir qual é a formatação atual do conteúdo do arquivo. Não tem como saber isso por comando. Imagina como seria perigoso popularizar um script que não consegue identificar o tipo atual de codificação antes de converter ?
A outra coisa é sobre as funções ZZ, você viu o último anúncio do Aurélio ? Ele tem aversão ao utf-8 e a própria precisa de conversão antes de ser usada em sistemas utf8.
Mas o maior problema é a identificação da codificação atual, como saber se o arquivo atual é X ou Y (ou Z, ou etc ...) ?
[]s
Conversão de ISO-8859-1 para UTF-8 em C++ utilizando iconv:
ReplyDeletestring toUtf8(const string &input)
{
const char *inptr = input.c_str();
char outbuf[input.length() * 2 + 1];
char *outptr = (char *) outbuf;
memset(outptr, 0, input.length() * 2 + 1);
size_t inbytes_left = input.length();
size_t outbytes_left = input.length() * 2;
iconv_t cd = iconv_open("UTF-8", "ISO-8859-1");
if (cd == (iconv_t)(-1)) {
printf("\n\nConversao nao suportada!\n");
return "";
}
int count = iconv(cd, &inptr, &inbytes_left, &outptr, &outbytes_left);
if (count < 0) {
if (errno == E2BIG) {
printf("\n\nErro (%d): Vetor de saida muito pequeno!\n", errno);
} else if (errno == EILSEQ) {
printf("\n\nErro (%d): Sequencia invalida de caracteres!\n", errno);
} else if (errno == EINVAL) {
printf("\n\nErro (%d): Sequencia incompleta de caracteres!\n", errno);
} else {
printf("\n\nErro (%d): Nao identificado!\n", errno);
}
return "";
}
string output = (string) outbuf;
return output;
}
Rafael, bom, muito bom mesmo e obrigado. Ainda não testei, mas provavelmente você me passou um pedaço de código que me será muito útil no futuro. Obrigado.
ReplyDeleteO único problema desse tipo de conversão é que se houverem arquivos já no formato UTF-8, eles serão convertidos novamente, o que corromperá o arquivo. Infelizmente o ICONV não é lá muito inteligente e não verifica se o arquivo já está no formato final ou não...
ReplyDeleteEdemilson,
ReplyDeletevocê conhece algum software de terminal que saiba me dizer qual é a codificação de um certo arquivo ?
Infelizmente eu não conheço nenhum. Já procurei muito, especialmente porque queria adicionar essa inteligência ao sistema, mas ...
Abraços.
E aí, Mitre, beleza?
ReplyDeleteLá vou eu ressuscitar tópico!
Nas minhas andanças pelo google em busca de informações sobre codificação de caracteres, descobri o seu blog, e consequentemente, o script do Marcelo. Ao editar o script para usar em meu sistema, descobri um aplicativo interessante que provavelmente já está por padrão instalado na distro que eu uso (Ubuntu 8.04): o utf8tolatin1.
Consultando a man page do utf8tolatin1, descobri que ele faz exatamente aquilo que eu precisava, e funciona.
Tem outro aplicativo, muito util por sinal, que serve pra fazer exatamente o que você precisa, o file, normalmente localizado em /usr/bin/file. É só dar um which file que você encontra. Ele serve pra identificar o tipo de arquivo do argumento que é passado pra ele, não apenas arquivos de texto. simplesmente digite "file nome-do-arquivo" e ele vai dizer, se for arquivo de texto, a codificação dos caracteres do mesmo.
Espero ter ajudado!
Abraços!
Bob, esse é um dos tópicos mais lidos do blog...
ReplyDeleteQualquer informação adicional que seja colocado aqui certamente ajudará alguém...
Sua informação, no mínimo, vai ajudar a mim, e muito.
Agora que sei que posso descobrir qual é a codificação de um arquivo com
file --mime-encoding texto.txt
eu tenho um mundo aberto. Muito obrigado.
Aliás, esse tópico necessita de uma repaginada, porque é muito importante manter a informação dele atualizada.
Um exemplo disso é o utf8latin1 que comentou, eu não conheço (ou pelo menos não me lembro sobre) esse script/programa, mas vou verificar.
Na época que eu escrevi esse tópico, o ubuntu ainda não oferecia uma conversão para o conteúdo dos arquivos, apenas para o nome dos arquivos e não checava para ver se ele havia sido convertido antes, de forma que não era possível rodar o programa duas vezes.
É bom saber que não deixaram de atualizar essa necessidade.
Um abraço e obrigado.
J. F. Mitre
E aí, tudo bem?
ReplyDeleteUpdate do comentário.
Esta aqui é a man page do programa que eu mencionei no comentário anterior: http://linux.die.net/man/1/utf8tolatin1
E este é o código-fonte do cidadão: http://tiny.cc/utf8tolatin1
E agora que eu li de novo este tópico, percebi que já tem 3 anos que você postou isto, o que mostra que problemas com diferentes codificações de caracteres ocorrem há muito tempo e com muita frequência.
Esta é a maravilha do software livre: todo mundo se ajuda, e cada um contribui como pode.
Abraços!
P.S.: Se houver problemas com os links, bobandiara arroba gmail ponto com.
Muitíssimo obrigado por essa iniciativa. Parabéns.
ReplyDeleteAqui o script já modificado para converter somente os arquivos textos em utf-8
ReplyDeleteFaçam bom proveito!
#!/bin/bash
# 04/07/2007
# por Marcelo Oliveira - www.iboletim.com.br
# modificado por Benneh Carvalho - www.sempirataria.wordpress.com
# Licença de uso: GPL
# ATENÇÃO: Um detalhe importante é que o script não suporta caminhos ou nomes que contenham espaços
# uso:
# utf2iso.sh diretorio-a-ser-convertido
# fecha se nao for fornecido nenhum argumento
if [ $# -eq 0 ]
then
echo "ERRO: especifique o nome da pasta com os arquivos a serem convertidos!"
echo "Uso: ./utf2iso.sh diretorio-a-ser-convertido"
exit 1
fi
# cria diretorio para armazenar arquivos convertidos
cp -R $1 iso-8859-1
# acessa diretorio com os arquivos a serem convertidos
cd $1
# cria lista de todos os arquivos utf-8 que serao convertidos
lista='file --mime-encoding *.txt | grep utf-8'
# executa conversao
for i in $lista
do
echo "convertendo... $i"
iconv -f utf-8 -t iso-8859-1 $i > ../iso-8859-1/$i;
#read; # para verificar as mensagens de erro
done
if [ $? == 0 ]
then
echo -e "\nConversao terminada com sucesso!\n"
fi
-----
Um Abraço a todos!
Benneh Carvalho
sempirataria.wordpress.com
Amigos, sei que tudo que foi explicado aqui refere-se a Linux, mas alguém conhece alguma solução para a que conversão seja realizada no Windows? Por favor não me crucifiquem estou apenas buscando informação, como disse o amigo ali em cima, no único site que encontrei que fala a respeito do assunto. Obrigado a todos!
ReplyDeleteAnderson,
ReplyDeletevocê pode instalar o cygwin que é um porte de algumas ferramentas linux para o windows, mas não sei se vai fazer o que você quer ... teria que testar (ou esperar que alguém comente aqui algo do tipo).
você pode instalar o vim para o windows (o vim é um editor bem poderoso típico do linux, mas possui versão nativa no windows), que certamente lhe dará acesso a esse tipo de solução (embora eu não tenha certeza se isso seria algo simples). Outra solução de programa seria instalar o KDE no windows, assim, você teria acesso a programas como o Kate/Kedit que resolveriam o seu problema.
Se não tiver muito espaço em HD, pode até experimentar o linux em um live CD através de um VirtualBox ou VMWare da vida. Por não precisar de instalar nada, consome pouco espaço (apenas a instalação do Virtualbox) e resolve o problema com razoável eficiência (se souber alguma coisa sobre o uso do Virtualbox e o mínimo conhecimento do uso do Linux ou de paciência para aprender sobre o mesmo).
O que eu não sei é se existe uma solução simples para esse problema dentro do windows apenas.
Já sofri muito com esse problema quando arquivos disponibilizados via rede Samba vinham para o meu computador e sem cerimônias estavam com codificação totalmente diferente. Felizmente, era eu que usava o Linux, então eu não tinha problemas. De fato, esse problema data da época que criei esse tópico.
rapaz... agora que percebi que fui coveiro do post hehehe obrigado pela sugestão... consegui utilizando o Ubuntu, não imaginava que fosse tão simples a instalação e utilização do Linux!!
ReplyDeleteBem, esse é o tópico mais visitado do meu blog e o mais comentado também. Desde 2006, em todos os anos, ele recebeu comentários, adições etc e tal.
ReplyDeleteInclusive, eu já criei um tópico mais recente sobre o assunto (revivendo o texto base e acrescentando novas informações com base nos comentários...), mas o Google conhece esse aqui melhor do que o novo...
Para quem não tem aversão a computadores e possui uma pequena vontade de aprender, o Linux é bem simples.
Obrigado pelo post. Hoje você me salvou fazendo uma conversão de um banco de dados de iso8859-1 para utf-8...
ReplyDeleteOla, qual seria um comando para saber se meu arquivo esta codificado em UTF-8 ou ISO88591. Uso CentOS 5.5
ReplyDeletefile --mime-encoding nomedoarquivo
ReplyDeleteVerifique a versão atualizada do texto que também foi escrito nesse blog para mais informações.
Um comando para verificar o tipo de codificação de um arquivo seria:
ReplyDeletefile -i arquivo | awk -F ';' '{print $2}';
Esse post salvou minha vida, muito obrigada! =)
ReplyDeleteMuito bom o artigo, já tive esse problema algumas vezes, agora ficou bem mais facil resolver! Obrigado
ReplyDeleteEncontrei esse tópico que foi bastante útil.
ReplyDeleteAcontece que a variável $lista fica com algo do tipo:
nome1.txt: utf-8
nome2.txt: utf-8
E isso causa erros em iconv.
Corrigi a filtragem da seguinte maneira:
lista=`file --mime-encoding *.txt | grep utf-8 | cut -d: -f1'
Dessa maneira a variável conterá apenas o nome do arquivo, sem o separador e sem o tipo do arquivo.
Nossa, nunca imaginei que poderia ser tão simples. Obrigado!
ReplyDelete