Corrigindo nomes de arquivos com charset errado

Publicado por Davidson Rodrigues Paulo em 16/08/2006

[ Hits: 25.144 ]

Blog: http://davidsonpaulo.com/

 


Corrigindo nomes de arquivos com charset errado



Muitas vezes, ao copiar arquivos de um computador para outro, principalmente via CD, os nomes dos arquivos ficam desajustados, mais especificamente os caracteres acentuadas e a cedilha. Por exemplo, um arquivo "Já Refulge a Glória Eterna.mp3" aparece como "Já Refulge a Glória Eterna.mp3".

Esse problema está relocionado ao charset do sistema de origem e o do seu sistema, que são diferentes. Entretanto, podemos facilmente resolver o problema e, com apenas um único comando, corrigir os nomes de todos os arquivos e diretórios presentes em um diretório qualquer.

Antes de mais nada, temos que saber qual o charset do seu sistema e o dos nomes dos arquivos. Para saber o charset do seu sistema, execute o comando locale. A saída será parecida com essa:

$ locale
LANG=pt_BR
LC_CTYPE="pt_BR"
LC_NUMERIC="pt_BR"
LC_TIME="pt_BR"
LC_COLLATE="pt_BR"
LC_MONETARY="pt_BR"
LC_MESSAGES="pt_BR"
LC_PAPER="pt_BR"
LC_NAME="pt_BR"
LC_ADDRESS="pt_BR"
LC_TELEPHONE="pt_BR"
LC_MEASUREMENT="pt_BR"
LC_IDENTIFICATION="pt_BR"
LC_ALL=pt_BR

O charset padrão do Linux é o ISO-8859-1 (também conhecido como Latin1). Sendo assim, tanto pt_BR quanto pt_BR.ISO8859-1 são para esse charset. Se, por outro lado, aparecer algo como pt_BR.UTF-8, então o charset do seu sistema é UTF-8.

Agora, vamos verificar o charset dos nomes dos arquivos. Para isso, acesse o diretório onde estão os arquivos e faça o seguinte procedimento:

$ ls -1 > lista
$ file lista

lista: UTF-8 text

Ou seja, o charset dos nomes dos arquivos é UTF-8, enquanto o do sistema é ISO-8859-1. Com essa informação em mãos, basta executar o seguinte comando, para corrigir os nomes dos arquivos:

$ ls -1 | while read arquivo ; do
novo="`echo $arquivo | iconv -f UTF-8 -t ISO-8859-1`"
if [ "$novo" != "$arquivo" ] ; then
mv "$arquivo" "$novo"
fi done


O segredo está no comando iconv, que converte o charset, de UTF-8 (-f UTF-8) para ISO-8859-1 (-t ISO-8859-1). Se no seu sistema os charsets forem outros, basta trocar ISO-8859-1 e UTF-8 pelos respectivos charsets.

Agradecimentos especiais ao Eduardo por ajudar na melhoria dessa dica, indicando uma situação onde ela não se aplicava (vide comentários abaixo).

Abraços,

Davidson

Outras dicas deste autor

Coaching Gratuito em Linux

Disquete no Linux sem precisar desmontar

Encontro virtual do projeto BrOffice.org

Fazendo o rpm voltar a funcionar depois de remover o sqlite

Baixando todos os arquivos de uma URL com o wget

Leitura recomendada

Livro de linguagem Pascal de graça

Jogos travando ao usar Compiz?

Tabela de horário de verão 2007/8

O verdadeiro motivo para não usar SIGKILL [HQ]

Complementando artigo sobre integração do Linux ao AD

  

Comentários
[1] Comentário enviado por paulodreher em 16/08/2006 - 13:08h

Muito interessante, alem disso bastante util!
Nota 10

[2] Comentário enviado por pedemesa em 16/08/2006 - 14:11h

Showtime!!! Muito útil!!! nem sabia desse comando "iconv" muito bom!

[3] Comentário enviado por edupbar em 10/12/2006 - 19:07h

colegas... tentei fazer o descrito mas da erro, será que é pq os meus arquivos estão com espaços entre o nome?
Segue os passos:
[eduardo@linux Babado Novo]$ ls
aaaa [Babado Novo] - Não Chore Mais.mp3
[Babado Novo] - Amor de Rapariga.mp3 [Babado Novo] - Não, Não.mp3
[Babado Novo] - Ã? na madeira.mp3 [Babado Novo] - Peixinho.mp3
[Babado Novo] - Cai Fora.mp3 [Babado Novo] - Perdi a minha Paz.mp3
[Babado Novo] - Canudinho.mp3 [Babado Novo] - Pot-Pourri.MP3
[Babado Novo] - Chaveca (ao vivo).mp3 [Babado Novo] - Regae Jamaicano.mp3
[Babado Novo] - Colchão e Fronha.mp3 [Babado Novo] - Saia rodada.mp3
[Babado Novo] - Don't Go (Ao Vivo).mp3 [Babado Novo] - Sorte Grande (Ao Vivo).mp3
[Babado Novo] - Então vem.mp3 [Babado Novo] - Tá Na Boca Do Povo (Ao vivo).mp3
[Babado Novo] - Escovadinha.mp3 [Babado Novo] - Uau!.mp3
[Babado Novo] - Eu Fico (ao vivo).mp3 [Babado Novo] - Vem Me Namorar.mp3
[Babado Novo] - Faraó.mp3 [Babado Novo] - You Don't Have To Go.mp3
[Babado Novo] - Fissura.mp3 lista
[Babado Novo] - Lirirrixa.mp3 script
[Babado Novo] - Mãozinha Mãozinha.mp3
[eduardo@linux Babado Novo]$ ls -l > lista
[eduardo@linux Babado Novo]$ file lista
lista: UTF-8 Unicode text
[eduardo@linux Babado Novo]$ for arquivo in `ls -l` ; do
> novo="`echo $arquivo | iconv -f UTF-8 -t ISO-8859-1`"
> if [ "$novo" != "$arquivo" ] ; then
> mv "$arquivo" "$novo"
> fi done
mv: impossível fazer stat em `Ã\211': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Colchão': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Então': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Faraó.mp3': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Mãozinha': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Mãozinha.mp3': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Não': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Não,': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Não.mp3': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Tá': Arquivo ou diretório não encontrado
[eduardo@linux Babado Novo]$

[4] Comentário enviado por davidsonpaulo em 11/12/2006 - 10:00h

edupbar,

Você digitou o comando ls com os parâmetros errados. O correto é ls -1 (éle-esse menos UM) e não ls -l (éle-ésse menos éle). Troque o l pelo 1 que o comando vai funcionar.

Abraço,

Davidson Paulo

[5] Comentário enviado por edupbar em 11/12/2006 - 21:06h

Cara, ls -1 também não resolveu...
[eduardo@linux Babado Novo]$ ls -1
[Babado Novo] - Amor de Rapariga.mp3
[Babado Novo] - Ã? na madeira.mp3
[Babado Novo] - Cai Fora.mp3
[Babado Novo] - Canudinho.mp3
[Babado Novo] - Chaveca (ao vivo).mp3
[Babado Novo] - Colchão e Fronha.mp3
[Babado Novo] - Don't Go (Ao Vivo).mp3
[Babado Novo] - Então vem.mp3
[Babado Novo] - Escovadinha.mp3
[Babado Novo] - Eu Fico (ao vivo).mp3
[Babado Novo] - Faraó.mp3
[Babado Novo] - Fissura.mp3
[Babado Novo] - Lirirrixa.mp3
[Babado Novo] - Mãozinha Mãozinha.mp3
[Babado Novo] - Não Chore Mais.mp3
[Babado Novo] - Não, Não.mp3
[Babado Novo] - Peixinho.mp3
[Babado Novo] - Perdi a minha Paz.mp3
[Babado Novo] - Pot-Pourri.MP3
[Babado Novo] - Regae Jamaicano.mp3
[Babado Novo] - Saia rodada.mp3
[Babado Novo] - Sorte Grande (Ao Vivo).mp3
[Babado Novo] - Tá Na Boca Do Povo (Ao vivo).mp3
[Babado Novo] - Uau!.mp3
[Babado Novo] - Vem Me Namorar.mp3
[Babado Novo] - You Don't Have To Go.mp3
lista
[eduardo@linux Babado Novo]$ for arquivo in `ls -1`; do novo="`echo $arquivo | iconv -f UTF-8 -t ISO-8859-1`"; if [ "$novo" != "$arquivo" ] ; then mv "$arquivo" "$novo"; fi done
mv: impossível fazer stat em `Ã\211': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Colchão': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Então': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Faraó.mp3': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Mãozinha': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Mãozinha.mp3': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Não': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Não,': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Não.mp3': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Tá': Arquivo ou diretório não encontrado
[eduardo@linux Babado Novo]$

[6] Comentário enviado por davidsonpaulo em 12/12/2006 - 09:23h

edupbar,

Achei o problema. Basta usar o comando "read" para capturar os nomes dos arquivos. O seguinte comando funciona:

ls -1 | while read arquivo ; do novo="`echo $arquivo | iconv -f UTF-8 -t ISO-8859-1`" ; if [ "$novo" != "$arquivo" ] ; then mv "$arquivo" "$novo" ; fi ; done

O comando é o mesmo, a única diferena é que ao invés de "for arquivo in `ls -1" você coloca "ls -1 | while read arquivo".

[7] Comentário enviado por sadol666 em 30/10/2007 - 16:57h

alguem sabe me dizer pq o parametro -R nao funciona?
se eu executo o comando sem ele funciona corretamente..
mais eu preciso corrigir os nomes tbm nas sub pastas..


kurumin@kurumin:/mnt/hdd1/backup$ ls -1 -R | while read arquivo ; do novo="`echo $arquivo | iconv -f UTF-8 -t ISO-8859-1`" ; if [ "$novo" != "$arquivo" ] ; then mv "$arquivo" "$novo" ; fi ; done
mv: impossível fazer stat em `Serviços on-line': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Adobe Reader 7.0 - Português.msi': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Serviços': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Gráficos de pizza.htm': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Plano de fundo Gráficos de pizza.jpg': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Plano de fundo Ponche de frutas cítricas.gif': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Ponche de frutas cítricas.htm': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `técn.gif': Arquivo ou diretório não encontrado
mv: impossível fazer stat em `Técnico.htm': Arquivo ou diretório não encontrado

[8] Comentário enviado por Érico Schuch em 19/11/2007 - 02:44h

sadol666

substitua "ls -1 -R" por "find" que resolve.

[9] Comentário enviado por eduardofraga em 26/12/2008 - 18:24h



Segue as alterações que fiz:


find . -print | sed 's/ /\\ /g' | sed 's/^.\///g' | while read arquivo ; do
novo="`echo $arquivo | piconv -f iso-8859-1 -t utf8`"
if [ "$novo" != "$arquivo" ] ; then
mv "$arquivo" "$novo"
fi done





Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts