it-swarm.dev

Codificação Windows-1252 para UTF-8

Eu copiei certos arquivos de uma máquina Windows para uma máquina Linux. Portanto, todos os arquivos codificados do Windows (windows-1252) precisam ser convertidos em UTF-8. Os arquivos que já estão em UTF-8 não devem ser alterados. Estou planejando usar o utilitário recode para isso. Como posso especificar que o utilitário recode deve converter apenas os arquivos codificados no windows-1252 e não os arquivos UTF-8?

Exemplo de uso de recode:

recode windows-1252.. myfile.txt

Isso converteria myfile.txt do windows-1252 para UTF-8. Antes de fazer isso, gostaria de saber que myfile.txt é codificado no Windows-1252 e não codificado em UTF-8. Caso contrário, acredito que isso corromperia o arquivo.

31
Sam

Como você esperaria recodificar para saber que um arquivo é o Windows-1252? Em teoria, acredito que any file é um arquivo válido do Windows-1252, pois mapeia todos os bytes possíveis para um caractere.

Agora há certamente características que fortemente sugerem que é UTF-8 - se começar com o BOM UTF-8, por exemplo - mas elas não seriam definitivas.

Uma opção seria detectar se é realmente um arquivo UTF-8 completamente válido primeiro, suponho ... novamente, isso seria apenas sugestivo.

Eu não estou familiarizado com a própria ferramenta de recodificação, mas você pode querer ver se ela é capaz de gravar um arquivo de e para o mesmo codificação - se você fizer isso com um arquivo inválido (ou seja, um que contenha UTF inválido Seqüências de 8 bytes) pode converter as seqüências inválidas em pontos de interrogação ou algo similar. Nesse ponto, você poderia detectar que um arquivo é válido UTF-8, recodificando-o para UTF-8 e verificando se a entrada e a saída são idênticas.

Como alternativa, faça isso de forma programática em vez de usar o utilitário de recodificação - seria bastante simples em C #, por exemplo.

Apenas para reiterar: tudo isso é heurístico. Se você realmente não sabe a codificação de um arquivo, nada lhe dirá 100% de precisão.

37
Jon Skeet

você pode usar iconv:

iconv -f WINDOWS-1252 -t UTF-8 filename.txt

62
Gregory Pakosz

Aqui está uma transcrição de outra resposta que dei a uma pergunta semelhante:

Se você aplicar utf8_encode () a uma string UTF8, ela retornará uma saída UTF8 truncada.

Eu fiz uma função que resolve todos esses problemas. É chamado Encoding :: toUTF8 ().

Você não precisa saber qual é a codificação das suas strings. Pode ser Latin1 (iso 8859-1), Windows-1252 ou UTF8, ou a string pode ter uma mistura deles. Codificação :: toUTF8 () irá converter tudo para UTF8.

Eu fiz isso porque um serviço estava me dando um feed de dados todo bagunçado, misturando UTF8 e Latin1 na mesma string.

Uso:

$utf8_string = Encoding::toUTF8($utf8_or_latin1_or_mixed_string);

$latin1_string = Encoding::toLatin1($utf8_or_latin1_or_mixed_string);

Download:

https://github.com/neitanod/forceutf8

Atualizar:

Eu incluí outra função, Encoding :: fixUFT8 (), que irá corrigir todas as strings UTF8 que pareçam distorcidas. 

Uso:

$utf8_string = Encoding::fixUTF8($garbled_utf8_string);

Exemplos:

echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("FÃÂédÃÂération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");

irá produzir:

Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football

Update: Eu transformei a função (forceUTF8) em uma família de funções estáticas em uma classe chamada Encoding. A nova função é Encoding :: toUTF8 ().

9
Sebastián Grignoli

Não há uma maneira geral de saber se um arquivo é codificado com uma codificação específica. Lembre-se de que uma codificação não é mais do que um "acordo" de como os bits de um arquivo devem ser mapeados para os caracteres.

Se você não sabe quais dos seus arquivos já estão codificados em UTF-8 e quais estão codificados no windows-1252, você terá que inspecionar todos os arquivos e descobrir por si mesmo. No pior dos casos, isso poderia significar que você tem que abrir cada um deles com uma das duas codificações e ver se elas "parecem" corretas - ou seja, todos os caracteres são exibidos corretamente. Claro, você pode usar o suporte de ferramenta para fazer isso, por exemplo, se você tem certeza de que certos caracteres estão contidos nos arquivos que possuem um mapeamento diferente no windows-1252 vs. UTF-8, você pode fazer um grep para eles depois de executar os arquivos através de 'iconv' como mencionado por Seva Akekseyev.

Outro caso de sorte para você seria, se você sabe que os arquivos realmente contêm apenas caracteres que são codificados de forma idêntica tanto no UTF-8 quanto no windows-1252. Nesse caso, é claro, você já terminou.

8
kleiba

Se você quiser renomear múltiplos arquivos em um único comando - digamos que você queira converter todos os arquivos *.txt - aqui está o comando:

find . -name "*.txt" -exec iconv -f WINDOWS-1252 -t UTF-8 {} -o {}.ren \; -a -exec mv {}.ren {} \;
5
Anthony O.

Use o comando iconv .

Para garantir que o arquivo esteja no Windows-1252, abra-o no Bloco de Notas (no Windows) e clique em Salvar Como. O Notepad sugere a codificação atual como padrão; se for Windows-1252 (ou qualquer página de código de 1 byte), ele diria "ANSI".

2
Seva Alekseyev

Você pode alterar a codificação de um arquivo com um editor, como o notepad ++. Basta ir para codificação e selecione o que você deseja.

Eu sempre prefiro o Windows 1252

1
thanos.a

O UTF-8 não possui uma lista técnica, pois ela é supérflua e inválida. Onde uma BOM é útil é em UTF-16, que pode ser trocada por byte, como no caso da Microsoft. UTF-16 se para representação interna em um buffer de memória. Use UTF-8 para intercâmbio. Por padrão, o UTF-8, qualquer outra coisa derivada do US-ASCII e UTF-16, é ordem de byte natural/de rede. O Microsoft UTF-16 requer uma lista de materiais, pois ela é trocada por byte.

Para converter o Windows-1252 para ISO8859-15, primeiro converto o ISO8859-1 para o US-ASCII para códigos com glifos semelhantes. Eu então converto o Windows-1252 até ISO8859-15, outros glifos não ISO8859-15 para vários caracteres US-ASCII.

0
Andrew Buckeridge

Encontrado este documentação para o comando TYPE :

Converta um arquivo ASCII (Windows1252) em um arquivo de texto Unicode (UCS-2 le): 

For /f "tokens=2 delims=:" %%G in ('CHCP') do Set _codepage=%%G    
CHCP 1252 >NUL    
CMD.EXE /D /A /C (SET/P=ÿþ)<NUL > unicode.txt 2>NUL    
CMD.EXE /D /U /C TYPE ascii_file.txt >> unicode.txt    
CHCP %_codepage%    

A técnica acima (baseada em um script de Carlos M.) primeiro cria um arquivo com uma marca de ordem de byte (BOM) e, em seguida, acrescenta o conteúdo do arquivo original. CHCP é usado para garantir que a sessão está sendo executado com a página de código do Windows1252 para que os caracteres 0xFF e 0xFE (ÿþ) sejam interpretados corretamente.

0
Napfkuchen

Se tiver certeza de que seus arquivos são UTF-8 ou Windows 1252 (ou Latin1), você pode aproveitar o fato de que a recodificação sairá com um erro se você tentar converter um arquivo inválido.

Enquanto utf8 é válido Win-1252, o inverso não é verdadeiro: win-1252 NÃO é válido UTF-8. Assim:

recode utf8..utf16 <unknown.txt >/dev/null || recode cp1252..utf8 <unknown.txt >utf8-2.txt

Vai cuspir erros para todos os arquivos cp1252 e, em seguida, continue a convertê-los em UTF8.

Eu iria envolver isso em um script bash mais limpo, mantendo um backup de cada arquivo convertido.

Antes de fazer a conversão do conjunto de caracteres, você pode primeiro garantir que você tenha finais de linha consistentes em todos os arquivos. Caso contrário, a recodificação irá reclamar por causa disso, e poderá converter arquivos que já eram UTF8, mas que acabaram tendo os finais de linha errados.

0
mivk