Encontré una secuencia problemática de un archivo de texto supuestamente codificado en UTF-8. Lo extraño es que grep parece incapaz de coincidir con esta línea que no es 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
Lo mismo \xe4
ocurre, por ejemplo, ä
en el conjunto ASCII extendido. Sin embargo, filtrar los caracteres de control y imprimibles (rango ascii) el comando grep anterior debe coincidir con el \xe4
carácter. ¿Por qué no obtengo ningún resultado grep?
Respuesta1
e4 75
De hecho, es una secuencia utf8 ilegal. En utf8, un byte con el cuarteto más alto igual a 0xe introduce una secuencia de tres bytes. El segundo byte de dicha secuencia no puede ser 0x75, porque el cuarteto de orden superior de ese segundo byte (0x7) no está entre 0x8 y 0xb.
Esto explica por qué iconv rechaza ese archivo como utf8 no válido. ¿Quizás ya sea iso8859-1?
Para obtener un resumen de la codificación utf8, consulte estotabla de wikipedia
En cuanto a su problema grep, tal vez si especifica la configuración regional C/POSIX, donde los caracteres equivalen a bytes:
LC_ALL=C grep -P -n '[^\x00-\x7F]' corrupt_part.txt
Usando un sistema Ubuntu antiguo, GNU grep y un entorno que usa la configuración regional 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