Искусство программирования на языке сценариев командной оболочки
Шрифт:
# GNU версии sed и awk допускают использование "+",
# но его необходимо экранировать.
echo a111b | sed -ne '/a1\+b/p'
echo a111b | grep 'a1\+b'
echo a111b | gawk '/a1+b/'
# Все три варианта эквивалентны.
# Спасибо S.C.
Экранированные "фигурные скобки" -- \{ \} -- задают число вхождений предыдущего выражения.
Экранирование фигурных скобок -- обязательное условие, иначе они будут интерпретироваться как простые символы. Такой порядок использования, технически, не является частью основного набора правил построения регулярных выражений.
Выражение "[0-9]\{5\}" -- в точности соответствует подстроке из пяти десятичных цифр (символов
bash$ echo 2222 | gawk --re-interval '/2{3}/'
2222
Язык программирования Perl и некоторые версии egrep не требуют экранирования фигурных скобок.
Круглые скобки -- – - предназначены для выделения групп регулярных выражений. Они полезны при использовании с оператором "|" и при извлечении подстроки с помощью команды expr.
Вертикальная черта -- |– - выполняет роль логического оператора "ИЛИ" в регулярных выражениях и служит для задания набора альтернатив.
bash$ egrep 're(a|e)d' misc.txt
People who read seem to be better informed than those who do not.
The clarinet produces sound by the vibration of its reed.
Классы символов POSIX. [:class:]
Это альтернативный способ указания диапазона символов.
Класс [:alnum:]– - соответствует алфавитным символам и цифрам. Эквивалентно выражению [A-Za-z0-9].
Класс [:alpha:]– - соответствует символам алфавита. Эквивалентно выражению [A-Za-z].
Класс [:blank:]– - соответствует символу пробела или символу табуляции.
Класс [:cntrl:]– - соответствует управляющим символам (control characters).
Класс [:digit:]– - соответствует набору десятичных цифр. Эквивалентно выражению [0-9].
Класс [:graph:] (печатаемые и псевдографические символы) -- соответствует набору символов из диапазона ASCII 33 - 126. Это то же самое, что и класс [:print:], за исключением символа пробела.
Класс [:lower:]– - соответствует набору алфавитных символов в нижнем регистре. Эквивалентно выражению [a-z].
Класс [:print:] (печатаемые символы) -- соответствует набору символов из диапазона ASCII 32 - 126. По своему составу этот класс идентичен классу [:graph:], описанному выше, за исключением того, что в этом классе дополнительно присутствует символ пробела.
Класс [:space:]– - соответствует пробельным символам (пробел и горизонтальная табуляция).
Класс [:upper:]– - соответствует набору символов алфавита в верхнем регистре. Эквивалентно выражению [A-Z].
Класс [:xdigit:]– - соответствует набору шестнадцатиричных цифр. Эквивалентно выражению [0-9A-Fa-f].
bash$ grep [[:digit:]] test.file
abc=723
Эти символьные классы могут использоваться, с некоторыми ограничениями, даже
в операциях подстановки имен файлов (globbing).bash$ ls -l ?[[:digit:]][[:digit:]]?
– rw-rw-r-- 1 bozo bozo 0 Aug 21 14:47 a33b
Примеры использования символьных классов в сценариях вы найдете в Пример 12-14 и Пример 12-15.
Sed, awk и Perl, используемые в сценариях в качестве фильтров, могут принимать регулярные выражения в качестве входных аргументов. См. Пример A-13 и Пример A-19.
Книга "Sed & Awk" (авторы Dougherty и Robbins) дает полное и ясное представление о регулярных выражениях (см. раздел Литература).
18.2. Globbing -- Подстановка имен файлов
Bash, сам по себе, не распознает регулярные выражения. Но в сценариях можно использовать команды и утилиты, такие как sed и awk, которые прекрасно справляются с обработкой регулярных выражений.
Фактически, Bash может выполнять подстановку имен файлов, этот процесс называется "globbing", но при этом не используется стандартный набор регулярных выражений. Вместо этого, при выполнении подстановки имен файлов, производится распознавание и интерпретация шаблонных символов. В число интерпретируемых шаблонов входят символы * и ?, списки символов в квадратных скобках и некоторые специальные символы (например ^, используемый для выполнения операции отрицания). Применение шаблонных символов имеет ряд важных ограничений. Например, если имена файлов начинаются с точки (например так: .bashrc), то они не будут соответствовать шаблону, содержащему символ * [ 48 ] . Аналогично, символ ? в операции подстановки имен файлов имеет иной смысл, нежели в регулярных выражениях.
48
Подстановка таких имен файлов возможна, но только при условии, что символ точки будет явно присутствовать в шаблоне.
~/[.]bashrc # Не будет соответствовать имени ~/.bashrc
~/?bashrc # То же самое.
# Метасимволы не могут соответствовать символу точки при подстановке имен файлов.
~/.[b]ashrc # Имя ~./bashrc будет соответствовать данному шаблону
~/.ba?hrc # Аналогично.
~/.bashr* # Аналогично.
# Установка ключа "dotglob" отключает такое поведение интерпретатора.
# Спасибо S.C.
bash$ ls -l
total 2
– rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 a.1
– rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 b.1
– rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 c.1
– rw-rw-r-- 1 bozo bozo 466 Aug 6 17:48 t2.sh
– rw-rw-r-- 1 bozo bozo 758 Jul 30 09:02 test1.txt
bash$ ls -l t?.sh
– rw-rw-r-- 1 bozo bozo 466 Aug 6 17:48 t2.sh
bash$ ls -l [ab]*
– rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 a.1
– rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 b.1
bash$ ls -l [a-c]*
– rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 a.1
– rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 b.1
– rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 c.1
bash$ ls -l [^ab]*
– rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 c.1
– rw-rw-r-- 1 bozo bozo 466 Aug 6 17:48 t2.sh
– rw-rw-r-- 1 bozo bozo 758 Jul 30 09:02 test1.txt
bash$ ls -l {b*,c*,*est*}