Использование test2.txt

$ cat /tmp/test2.txt | hexdump -C
00000000  47 61 6c 6c 6f 20 63 65  6c 74 69 63 6f 0a 47 65  |Gallo celtico.Ge|
00000010  73 97 20 42 61 6d 62 69  6e 6f 0a                 |s. Bambino.|

Вот что случилось с awk:

$ cat /tmp/test2.txt | awk '/\x97/{print}'
Ges Bambino

$ cat /tmp/test2.txt | awk '/[\x7F-\xFF]/{next;}; 1'
Gallo celtico
Ges Bambino

Т.е. строка Ges Bambino содержит строку char \x97 , и awk подтверждает это в первой команде. Тем не менее, \x97 находится в диапазоне \x7F-\xFF поэтому строка должна быть пропущена во второй команде, но это не так.

Это действительно похоже на ошибку awk для меня.
Любые комментарии?

PS. делая это более очевидным:

$ cat /tmp/test2.txt | awk '/\x97/{next}; 1'
Gallo celtico

$ cat /tmp/test2.txt | awk '/[\x97]/{next}; 1'
Gallo celtico
Ges Bambino

ОБНОВИТЬ:

Как отметил @KamilMaciorowski, это связано с местным. Т.е. вышесказанное происходит когда под

$ set | egrep '^LANG|^LC'
LANG=zh_CN.UTF-8

тогда как оба

cat /tmp/test2.txt | LC_ALL=C awk '/[\x97]/{next}; 1'
cat /tmp/test2.txt | LC_ALL=C awk '/[\x7F-\xFF]/{next;}; 1'

дают правильные результаты.

Тем не менее, это проблема, не так ли?

1 ответ1

2

Байты и символы идентичны только в локали C (по умолчанию POSIX) по умолчанию, но во всех других локалях они различны. Таким образом, если ваша система по умолчанию использует локаль UTF-8 (например, en_US.UTF-8), то "классы символов" в скобках в регулярных выражениях gawk основаны на символах, а не на отдельных байтах.

Например, /[eęė]/ эквивалентно /[e\xC4\x99\xC4\x97]/ при условии *.UTF-8 локаль; однако он будет соответствовать букве ę но не č , несмотря на то, что оба имеют байт C4 . (По некоторым причинам, это отличается от обычного /\xC4/ вне класса символов, который делает соответствовать буквальным байтам C4

В любом случае, то же самое относится к диапазонам внутри классов символов, и поскольку байтовый FF не создает допустимую последовательность UTF-8, библиотека регулярных выражений может просто объявить весь диапазон недействительным или что-то в этом роде.

У gawk есть опция -b , --characters-as-bytes чтобы отключить это.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .