Conversão do conjunto de caracteres Unix

4

Estou confuso com conjuntos de caracteres no Unix. Eu tenho um arquivo CSV baixado via SFTP:

$ file -ib myfile
text/plain; charset=us-ascii

O objetivo dessa missão é que os dados dentro do arquivo sejam vistos como:

Flyers: Video Center

Enquanto eu quero:

Flyers: Video Center

Eu tentei:

iconv -f us-ascii -t utf-8 myfile

Qual é o seguinte erro:

iconv: illegal input sequence at position 528666

Por favor, esclareça o que está acontecendo em relação aos conjuntos de caracteres? Posso baixar em UTF-8 ao obter um arquivo via SFTP? Como geralmente decidimos o que é lixo dentro de um conjunto de caracteres?

$Locale  
LANG=en_US.UTF-8  
LC_CTYPE="en_US.UTF-8"  
LC_NUMERIC="en_US.UTF-8"  
LC_TIME="en_US.UTF-8"  
LC_COLLATE="en_US.UTF-8"  
LC_MONETARY="en_US.UTF-8"  
LC_MESSAGES="en_US.UTF-8"  
LC_PAPER="en_US.UTF-8"  
LC_NAME="en_US.UTF-8"  
LC_ADDRESS="en_US.UTF-8"  
LC_TELEPHONE="en_US.UTF-8"  
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=  
$  LC_ALL=C sed -n l  
Zimbabwe,175,Unknown Network,-1,Unknown,-1,Unknown,-1,US: Flyers: Video Center:,854088,Standard Display,-998,10/28/2014
$ iconv -f utf-8 -t l1   
iconv: illegal input sequence at position 1228354  

Quando definir Terminal (Em Transalação, caractere definido como UTF-8), poderei ver dados limpos.
Mas, quando eu li isso com codificação UTF-8 usando uma ferramenta ETL; os dados são lidos como lixo.

Quando eu grep meu arquivo para dados

"Flyers: Video Center" 

Não vejo resultado para o fato de os dados serem armazenados como

"Flyers: Video Center"

A codificação do arquivo pode ser alterada para ver o que eu quero?

hexdump para caracteres indesejados:

0000000: 4e42 4353 3a20 4e48 4c2e 636f 6d3a 2055  NBCS: NHL.com: U  
0000010: 533a 2046 6c79 6572 733a c2a0 5669 6465  S: Flyers:..Vide  
0000020: 6fc2 a043 656e 7465 723a 2057 6861 7427  o..Center: What'  
0000030: 7320 486f 740a                           s Hot.  


$dd bs=1 skip=1228300 count=100 < temp1.csv | xxd  
100+0 records in  
100+0 records out  
100 bytes (100 B) copied, 0.000141 seconds, 709 kB/s  
0000000: 3031 342c 320a 556e 6b6e 6f77 6e20 436f  014,2.Unknown Co  
0000010: 756e 7472 792c 2d31 2c48 756c 7520 4c69  untry,-1,Hulu Li  
0000020: 7665 2c33 3738 3834 312c 4e42 433a 2041  ve,378841,NBC: A  
0000030: 6d65 7269 6361 e280 9973 2047 6f74 2054  merica...s Got T  
0000040: 616c 656e 743a 2053 686f 7274 666f 726d  alent: Shortform    
0000050: 2c33 3230 3631 3332 2c55 6e6b 6e6f 776e  ,3206132,Unknown  
0000060: 2053 6974                                 Sit  

Algum texto ilegível:

Junk Americaâs   

deve ter sido (Note que o apóstrofo não é isso 'mas')

America’s

e

BMW â Golden  

deve ter sido (Observe que o hífen é longo hífen não isso -):

BMW – Golden 
    
por Abhishek 03.12.2014 / 11:39

2 respostas

1

Problema nº 1: grepping "Folhetos: Video Center" ... não vejo o resultado :

No despejo hexadecimal do arquivo, observe os dois bytes C2A0 entre as palavras Panfletos: e Vídeo . Esta é uma codificação UTF8 para Espaço sem quebra . o grepping NBSP é conhecido por falhar Para mais informações, leia Como remover especial 'M-BM - 'personagem com sed e usa sed para substituir ... Hex c2a0 . Resposta curta é:

sed -i.bak -e 's/\xc2\xa0/ /' /path/to/file

O problema nº 2 'America’s' é exibido como 'Americaâs' (??) :

Aqui, o dump contém três bytes e28099, conhecidos como MARCA DE COTAÇÃO ÚNICA CERTA ('). Na verdade, não deve haver problema aqui! Você provavelmente se distraiu com o problema acima (você poderia confirmar?)

Se você usa grep , sed e outras ferramentas com expressão que respeita sua localidade (UTF8!), então funcionará:

printf 'America\xe2\x80\x99s\n' | grep --only-matching "[[:punct:]]"
printf 'America\xe2\x80\x99s\n' | sed -e "s/[[:punct:]]/?/"

Se você quiser se livrar de todos os caracteres " especiais " do UTF-8, use pode usar as dicas acima ou iconv (mas atualmente, há poucas desculpas para não suportar o UTF8) .

Solte todos os caracteres não-ascii:

type a.txt | iconv -f utf8 -t ASCII//TRANSLIT

Ou para preservar caracteres de um local:

type a.txt | iconv -f utf8 -t iso8859-15//TRANSLIT | iconv -f iso8859-15 -t utf8
    
por 08.03.2015 / 21:51
1

Ao contrário do XML , que deve conter uma tag de codificação que descreva a codificação do conteúdo original, você precisa obter essa informação para o csv com outros meios.

Enquanto o type funciona muito bem em dados binários, ele não funciona bem em dados de texto.

Isso se deve à maneira como o comando funciona. veja man text . Grosso modo: Ele analisa os primeiros bytes e tenta adivinhar o conteúdo procurando o que foi encontrado em uma tabela de consulta.

Normalmente, é uma boa prática perguntar ao originador do conteúdo qual conjunto de caracteres foi usado.

Se isso não for possível - por qualquer motivo, iconv é seu melhor amigo aqui.

    
por 18.06.2016 / 09:32