Grep não corresponde a caracteres não-ascii

Grep não corresponde a caracteres não-ascii

Encontrei uma sequência problemática de um arquivo de texto supostamente codificado em UTF-8. O estranho é que o grep parece incapaz de corresponder a esta linha não-ASCII.

$ iconv -f utf8 -t iso88591 corrupt_part.txt --output corrupt_part.txt.conv
iconv: illegal input sequence at position 8
$ cat corrupt_part.txt
Oberallg�u
$ grep -P -n '[^\x00-\x7F]' corrupt_part.txt
$ od -h corrupt_part.txt
0000000 624f 7265 6c61 676c 75e4 0a20
0000014

O mesmo \xe4ocorre, por exemplo, äno conjunto ASCII estendido. Ainda assim, filtrar os caracteres de controle e imprimíveis (faixa ascii) o comando grep acima deve corresponder ao \xe4caractere. Por que não estou obtendo nenhuma saída do grep?

Responder1

e4 75é de fato uma sequência utf8 ilegal. Em utf8, um byte com o maior nibble igual a 0xe introduz uma sequência de três bytes. O segundo byte dessa sequência não pode ser 0x75, porque o nibble de ordem superior desse segundo byte (0x7) não está entre 0x8 e 0xb.

Isso explica por que o iconv rejeita esse arquivo como utf8 inválido. Talvez já seja iso8859-1?

Para um resumo da codificação utf8, consulte estetabela da Wikipédia

Quanto ao seu problema com o grep, talvez se você especificar o código do idioma C/POSIX, onde os caracteres são equivalentes a bytes:

LC_ALL=C grep -P -n '[^\x00-\x7F]' corrupt_part.txt

Usando um sistema Ubuntu antigo, GNU grep e um ambiente usando a localidade en_US.UTF-8:

$ od -h bytes
0000000 624f 7265 6c61 676c 75e4 0a20
0000014
$ grep -P '[^\x00-\x7F]' bytes | od -h
0000000 624f 7265 6c61 676c 75e4 0a20
0000014
$ LC_ALL=C grep -P '[^\x00-\x7F]' bytes | od -h
0000000 624f 7265 6c61 676c 75e4 0a20
0000014

informação relacionada