Я только что нашел ошибку в awk?

287
xpt

Использование 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/' Ges Bambino  $ cat /tmp/test2.txt | awk '/[\x7F-\xFF]/; 1' Gallo celtico Ges Bambino 

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

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

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

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

ОБНОВИТЬ:

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

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

тогда как оба

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

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

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

0
Это то же самое, когда вы запускаете `LC_ALL = C awk…`? Также [вам не нужен `cat` здесь] (https://en.wikipedia.org/wiki/Cat_ (Unix) #Useless_use_of_cat), я думаю. Kamil Maciorowski 6 лет назад 0
Я не могу воспроизвести проблему; это может быть связано с вашей локалью. Какой вывод у `set | egrep '^ LANG | ^ LC'`? Kamil Maciorowski 6 лет назад 0
@KamilMaciorowski: Истинный последователь философии Unix вместо этого похвалил бы одного за использование каналов, не так ли? grawity 6 лет назад 0
@KamilMaciorowski, действительно, это связано с языком. ОП обновлен. xpt 6 лет назад 0

1 ответ на вопрос

2
grawity

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

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

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

простак имеет -b, --characters-as-bytesвозможность отключить это.

Похожие вопросы