Como recodificar a UTF-8 condicionalmente?

2

Estou unificando a codificação de um grande grupo de arquivos de texto, reunidos ao longo do tempo em diferentes computadores. Eu estou indo principalmente de ISO-8859-1 para UTF-8. Isso converte muito bem um arquivo:

recode ISO-8859-1..UTF-8 file.txt

Eu, claro, quero fazer o processamento em lote automatizado para todos os arquivos, e simplesmente executar o acima para cada arquivo tem o problema de que arquivos codificados em UTF-8 terão sua codificação quebrada . (Por exemplo, o caractere 'ä' originalmente em ISO-8859-1 aparecerá assim, visto como UTF-8, se a recodificação acima for feita duas vezes: � -> ä -> ä )

A minha pergunta é, que tipo de script seria executado apenas se necessário , ou seja, apenas para arquivos que ainda não estavam na codificação de destino (UTF-8 no meu caso)?

Olhando a página man recode, não consegui descobrir como fazer algo assim. Então eu acho que isso se resume a como verificar facilmente a codificação de um arquivo, ou pelo menos se é UTF-8 ou não. Esta resposta significa que você pode reconhecer UTF-8 válido arquivos com recode, mas como? Qualquer outra ferramenta também estaria bem, contanto que eu pudesse usar o resultado em um condicional em um script bash ...

    
por Jonik 06.03.2010 / 17:03

5 respostas

3

Este script, adaptado da ideia de harrymc , que recodifica condicionalmente um arquivo (baseado na existência de certos caracteres escandinavos codificados em UTF-8), parece funcionar razoavelmente bem para mim.

$ cat recode-to-utf8.sh 

#!/bin/sh
# Recodes specified file to UTF-8, except if it seems to be UTF-8 already

result='grep -c [åäöÅÄÖ] $1' 
if [ "$result" -eq "0" ]
then
    echo "Recoding $1 from ISO-8859-1 to UTF-8"
    recode ISO-8859-1..UTF-8 $1 # overwrites file
else
    echo "$1 was already UTF-8 (probably); skipping it"
fi

(Arquivos de processamento em lote são obviamente uma questão simples, por exemplo, for f in *txt; do recode-to-utf8.sh $f; done .)

NB : isso depende totalmente do próprio arquivo de script sendo UTF-8. E como esta é obviamente uma solução muito limitada adequada para o tipo de arquivos que eu tenho, sinta-se livre para adicionar melhores respostas que resolvam o problema de uma forma mais genérica.

    
por 06.03.2010 / 20:11
7

Esta mensagem é bastante antiga, mas acho que posso contribuir para este problema:
Primeiro crie um script chamado recodeifneeded :

#!/bin/bash
# Find the current encoding of the file
encoding=$(file -i "$2" | sed "s/.*charset=\(.*\)$//")

if [ ! "$1" == "${encoding}" ]
then
# Encodings differ, we have to encode
echo "recoding from ${encoding} to $1 file : $2"
recode ${encoding}..$1 $2
fi

Você pode usá-lo desta maneira:

recodeifneeded utf-8 file.txt

Então, se você gosta de executá-lo recursivamente e alterar todas as codificações de arquivos * .txt para (digamos) utf-8:

find . -name "*.txt" -exec recodeifneeded utf-8 {} \;

Espero que isso ajude.

    
por 20.02.2014 / 10:46
2

O UTF-8 tem regras estritas sobre quais seqüências de bytes são válidas. Isso significa que, se os dados puderem ser UTF-8, você raramente obterá falsos positivos se assumir que é .

Então você pode fazer algo assim (em Python):

def convert_to_utf8(data):
    try:
        data.decode('UTF-8')
        return data  # was already UTF-8
    except UnicodeError:
        return data.decode('ISO-8859-1').encode('UTF-8')

Em um script de shell, você pode usar iconv para realizar o converstion, mas precisará de um meio de detectar o UTF-8. Uma maneira é usar iconv com UTF-8 como as codificações de origem e destino. Se o arquivo for válido UTF-8, a saída será a mesma que a entrada.

    
por 21.08.2010 / 19:21
1

Tanto o ISO-8859-1 quanto o UTF-8 são idênticos nos primeiros 128 caracteres, então o seu problema é realmente como detectar arquivos que contenham caracteres engraçados, significando numericamente codificados como acima de 128.

Se o número de caracteres engraçados não for excessivo, você poderá usar o egrep para verificar e descobrir quais arquivos precisam ser recodificados.

    
por 06.03.2010 / 18:08
1

Estou um pouco atrasado, mas ando me esforçando tanto com a mesma pergunta de novo e de novo ... Agora que encontrei uma ótima maneira de fazer isso, não posso deixar de compartilhar: )

Apesar de ser um usuário do emacs, eu recomendo que você use o vim hoje.

com este comando simples, ele recodificará seu arquivo, não importa o que esteja dentro da codificação desejada:

vim +'set nobomb | set fenc=utf8 | x' <filename>

nunca encontrou algo que me desse resultados melhores do que isso.

Espero que ajude alguns outros.

    
por 27.04.2018 / 16:52