#awk
#awk
Вопрос:
Я хотел бы написать условие awk, которое соответствует строке, если она начинается с заглавной буквы. Вот пример файла данных.
a
b
c
A
B
C
d
e
Допустим, я хочу сопоставить все строки, которые соответствуют символам ABC.
awk '{ if ($1 ~ /^[ABC]/) print }' test
A
B
C
Достаточно просто. Но это не сработает, если я использую символьный класс. Регистр игнорируется.
awk '{ if ($1 ~ /^[A-C]/) print }' test
b
c
A
B
C
Интересно, что это работает:
awk '{ if ($0 ~ /^[[:upper:]]/) print }' < test
A
B
C
Из документации я бы ожидал, что команда будет:
awk '{ if ($0 ~ /^[:upper:]/) print }' < test
Что я неправильно понимаю? В частности, почему [A-C]
регистр не чувствителен и почему мне нужно писать [[:upper:]]
вместо [:upper:]
?
echo $LANG
en_US.utf8
Комментарии:
1. Я не вижу ваших результатов. Что содержит ваша
LANG
переменная окружения?2. Со страницы руководства gawk: символьный класс допустим только в регулярном выражении внутри скобок списка символов.
3. Возможно, я понимаю, о чем вы говорите. Мне нужно
[[A-C]]
?awk '{ if ($0 ~ /^[[A-C]]/) print }' test
выдает 0 результатов. То же самое для gawk.4. нет. предположим, вы хотите выполнить поиск шестнадцатеричной цифры, можно сказать,
/[[:digit:]a-fA-F]/
— так что[:character_class:]
находится внутри внешнего[brackets]
, как обычные символы5. Понял, я был сбит с толку, потому что иногда
[A-C]
упоминается как символьный класс (т. е. download.oracle.com/javase/tutorial/essential/regex /… и некоторых версияхman awk
), но не вman gawk
!
Ответ №1:
Что я неправильно понимаю? В частности, почему [A-C] не чувствителен к регистру
Вероятно, это связано с вашим языком, который может повлиять на диапазоны классов символов.
Попробуйте установить, export LC_ALL=C
а затем снова запустить свою awk
команду с [A-C]
почему мне нужно писать [[:upper:]] вместо [:upper:]?
[:upper:]
по сути, это способ записи диапазона A-Z
без учета локали, но вы также хотите, чтобы это был символьный класс, поэтому вы переносите его в []
, следовательно [[:upper:]]
. Так, например, если бы вы хотели сопоставить все символы верхнего регистра и цифры, вы бы написали [[:upper:][:digit:]]
Комментарии:
1. Это имеет прекрасный смысл (re: [:upper:]), но можете ли вы объяснить, почему
awk '{ if ($0 ~ /^[:upper:]/) print }' < test
возвращает толькоe
??2. Да, это была локальная проблема.
export LC_ALL=C
представил ожидаемый результат. Спасибо за совет!3. @schmid, это
[:upper:]
точно то же самое, что и это[epru:]
— скобки содержат набор символов, которые вы хотите сопоставить.