Friday, August 05, 2011

Como mudar o encoding de arquivo com conteúdo para UTF-8 no Linux

Alguns dias atrás trabalhei um projeto para customizar um portal para China. Nada muito complicado, afinal era só usar a estrutura do projeto já implementado no Brasil, EUA e outros países para a China.

Mas.... o portal foi projetado com o padrão de charset ISO-8859-1, que não suporta os caracteres do mandarim. A solução então era migrar a estrutura atual, em ISO-8859-1 para UTF-8, mas o buraco era mais embaixo!

São vários detalhes para resolver, por exemplo:
  • Configuração do ambiente servidor e desenvolvimento;
  • Configuração de web-server, application server e database;
  • Outros...

Aqui vou falar apenas de: arquivos texto com algum conteúdo/caractere especial.

O que fazer com os milhares de arquivos Java, JSP, HTML, JS, PHP e outros com algum caractere especial que foram transformados em �?

Lembrando que por se tratar de um projeto já implementado qualquer arquivo com caractere especial em ISO-8859-1 aberto em UTF-8 fica assim: �. Mudar o texto na mão, arquivo a arquivo era completamente fora de cogitação!

Ainda bem que o Linux quebrou nosso galho, e converteu a codificação dos caracteres especiais de um charset para outro, com o mínimo de esforço! Graças ao programa: iconv

Como utilizar o iconv?
$ iconv -f [charset original] -t [charset desejado] < [arquivo original] > [novo arquivo charset desejado]
$ iconv -f ISO-8859-1 -t UTF-8 < htmlEspecial.html > htmlEspecialNovo.html

O iconv considera o conteúdo do arquivo atual (original) no charset indicado e converte o conteúdo, no caso o(s) caractere(s) especial para o novo charset indicado. Portanto, o arquivo htmlEspecialNovo.html não vai conter o símbolo �, e sim o caractere na formatação correta.

Ficou fácil, mas executar o iconv arquivo a arquivo também seria muito trabalhoso, além de que o objetivo era substituir o arquivo para o novo charset sem criar um novo arquivo.

Pra ficar mais fácil ainda meu brother Gimenez, bolou um script bash para executar processar o iconv para todos os arquivos a partir de uma pasta com filtro na extensão do arquivo.

#!/bin/bash

ICONVBIN='/usr/bin/iconv'

if [ $# -lt 3 ]
then
    echo "$0 from_charset to_charset extesion"
    exit
fi

for f in `find ./ -name "*.$3" -exec file --mime {} \; | grep $1 | cut -f 1 -d :`
do
    if test -f $f
    then
        echo -e "\nConvertendo $f"
        /bin/mv $f $f.old
        RETMV=$?
        if [ $RETMV -gt 0 ]; then
          echo -e "\n Atencao erro no mv"
          exit 1
        fi

        $ICONVBIN -f $1 -t $2 $f.old > $f
        RETICONV=$?
        if [ $RETICONV -gt 0 ]; then
          echo -e "\n Atencao erro no iconv"
          exit 2
        fi

        /bin/rm $f.old
        RETRM=$?
        if [ $RETRM -gt 0 ]; then
          echo -e "\n Atencao erro no rm"
          exit 3
        fi
    else
        echo -e "\nArquivo $f nao convertido";
    fi
done
 

A execução do script convert seria algo do tipo:
> convert iso-8859-1 utf8 java


@edermag
www.yaw.com.br

No comments: