Я нашел проблемную последовательность текстового файла, предположительно закодированного в UTF-8. Странно, что grep, похоже, не может сопоставить эту не-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
Так \xe4
, например, ä
в расширенном наборе ASCII. Тем не менее, фильтрация по управляющим и печатным символам (диапазон ascii) команда grep выше должна соответствовать \xe4
символу. Почему я не получаю никакого вывода grep?
решение1
e4 75
действительно является недопустимой последовательностью utf8. В utf8 байт с наивысшим полубайтом, равным 0xe, вводит трехбайтовую последовательность. Второй байт такой последовательности не может быть 0x75, поскольку наивысший полубайт этого второго байта (0x7) не находится между 0x8 и 0xb.
Это объясняет, почему iconv отклоняет этот файл как недопустимый utf8. Возможно, он уже iso8859-1?
Для получения краткой информации о кодировке utf8 обратитесь к этомутаблица википедии
Что касается вашей проблемы с grep, возможно, если вы укажете локаль C/POSIX, где символы эквивалентны байтам:
LC_ALL=C grep -P -n '[^\x00-\x7F]' corrupt_part.txt
Используя старую систему Ubuntu, GNU grep и среду, использующую локаль 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