RegEx в bash

В bash регулярки доступны в составной команде [[ при использовании сравнения =~, к примеру, в операторе if .
Но всё равно регулярки доступны в grep/sed/awk.

Регулярки в grep

Про grep: grep

Есть 3 способа сообщить команде grep, что нужно специальное значение для определенных символов:

  1. добавить перед этими символами обратный слеш \
  2. сообщить grep, что вам специальный синтаксис (без обратного слеша), используя при вызове grep параметр -E
  3. добавить команду egrep - скрипт, вызывающий grep как grep -E.

Единственные символы, на которые влияет расширенный синтаксис, - это +{()|.


Метасимволы

Регулярные выражения - шаблоны, созданные с использованием последовательности символов и метасимволов. Такие метасимволы, как знак вопроса ? и звездочка *, помимо непосредственного значения, в регулярном выражении имеют специальное значение.

Метасимвол .

В RegEx точка . - один символ подстановки - один любой символ.

grep 'T.o' test.txt

Найдутся “слова” по типу: Two, T1o, T.o и т.д.
Но НЕ To, ибо между T и o должен находится один символ.
(Разжевал, ELYF.)

Метасимвол ?

Знак вопроса ? делает любой предыдущий символ необязательным.

egrep 'T.?o' test.txt
grep -E 'T.?o' test.txt
# RegEx в bash

Найдутся “слова” по типу: Two, To и т.д.

Метасимвол *

Звездочка * соответствует предыдущему символу неограниченное кол-во раз.

grep 'T.*o' test.txt

Найдется что-то по типу: Two, To, The Ro и т.д.

Метасимвол +

Знак плюса + похож на звездочку *, за исключением того, что предыдущий ему элемент должен встретиться хотя бы однажды.

grep 'T.+o' test.txt

Найдется что-то по типу: Two, The Ro, и т.д.
Но НЕ To.

Группирование

Для группирования можно юзать скобки ().
Это позволит еще рассматривать расположенные внутри скобок символы как один элемент, если юзать вертикальную черту | как оператор ИЛИ.

egrep 'And be one (stranger|traveler), long I stood' test.txt
# And be one traveler, long I stood

Квадратные скобки и классы символов

В RegEx квадратные скобки [] определяют классы и списки допустимых символов.
Для краткости при указании диапазона можно юзать тире -, например, [a-j]. Здесь работает сортировка в алфавитном порядке, то есть, , буквы от a до j.

Диапазоны символов регулярок

ПримерЗначение
[abc]Только символы a, b, или c
[1–5]Цифры от 1 до 5
[a–zA–Z]Любая строчная и прописная буква (от a до z
[0–9 +–*/]Числа или указанные математические операторы (+ пробел)
[0–9a–fA–F]Любой шестнадцатеричный символ

Осторожнее с диапазоном для цифр

Диапазон для цифр может быть от 0 до 9.
Например, шаблон н [1–475] НЕ соответствует числам от 1 до 475; он соответствует любой из цифр (символов) в диапазоне [1–4], или символу 7, или символу 5.

Сокращения регулярок

Сокращения регулярных выражений - предопределенные символьные классы, которые можно юзать для обозначения общих классов символов, по типу цифр или букв.

СимволЗначение
\sПробельный символ
\SНепробельный символ
\dЦифровой символ
\DНецифровой символ
\wСлово
\WНе слово
\xШестнадцатеричное число (например, 0x5F

Эти сокращения НЕ поддерживаются командой egrep. Чтобы их применить, надо юзать grep -P, т.к. это Perl фичи.

Например, чтобы найти любые числа, нужно:

grep -P '\d' test.txt

Другие символьные классы (с более подробным синтаксисом) работают только внутри скобок. + Они соответствуют одному символу, поэтому если нужно “найти несколько”, юзай * или + .

Классы символов

Все есть здесь: Классы символов


Обратные ссылки на регулярки

Обратные ссылки на регулярные выражения - одни из самых мощных (и часто кажущихся сложными) операцией регулярных выражений.

Файл tags.txt для примера:

1    Command
2    <i>_line_</i>
3    is
4    <div>great</div>
5    <u>!</u>

Если нужен RegEx, который будет извлекать любую строку, содержащую соответствующую пару полных тегов HTML (пример примитивный, для HTML-кода, где теги стоят на разных строках, придется другой метод юзать):

egrep '<([A-Za-z]*)>.*</\1>' tags.txt

Результат:

2    <i>_line_</i>
4    <div>great</div>
5    <u>!</u>

В примере выше обратная ссылка \1 стоит в последней части RegEx. Она направляет к выражению в первом наборе скобок, [A-Za-z]*, которое состоит из двух частей:

  1. Диапазон букв в скобках обозначает, что может быть выбрана любая буква, прописная или строчная.
  2. \1 ссылается на соответствующий шаблон, который задан в скобках. Если [A-Za-z]* соответствует div, то \1 также ссылается на шаблон div.

Можно юзать несколько обратных ссылок в выражении и обращаться к каждой как \1, \2, \3 (и т.д.) в зависимости от ее порядка в RegEx. Круглые скобки являются метасимволами. Если нужно найти соответствие круглой скобке - надо будет исключить ее специальное значение (сделав ее обычным символом), поставив перед ней обратный слеш. Например, пиши sin\([0-9.]*\), чтобы найти такие выражения, как sin(6.2) или sin(3.14159).

Квантификаторы

Квантификаторы указывают, сколько раз элемент должен появиться в строке, и определяются фигурными скобками {}.

Например, шаблон T{5} означает, что буква T должна последовательно появляться ровно 5 раз.
Шаблон T{3,6} означает, что буква T должна появляться последовательно от трех до шести раз.
Шаблон T{5,} означает, что буква T должна появляться пять раз или более.

Якоря и границы слов

Если нужно указать, что шаблон должен находиться в начале или в конце строки, можно юзать якоря.

Символ каретки ^

Символ каретки ^ привязывает шаблон к началу строки.
Например, ^[1-5] означает, что соответствующая строка должна начинаться с одной из цифр от 1 до 5.

Символ доллара $

Символ $ используется для привязки шаблона к концу последовательности или строки.
Например, [1-5]$ означает, что строка должна заканчиваться одной из цифр от 1 до 5.
Вообще, можно юзать \b для определения границы слова (то есть обозначить пробел). Шаблон \b[1-5]\b будет соответствовать любой из цифр от 1 до 5, где цифра представлена словом.


Соус: Книга “Bash и кибербезопасность Глава 3. “Регулярные выражения