linux-labs

Вики / Базовые команды

Регулярные выражения

Концепция POSIX / PCRE БазовоеТекст и потоки

Шаблоны для grep/sed/awk — символы, классы, якоря, группы; базовые vs расширенные.

Регулярки — язык шаблонов для поиска в тексте. Используются в grep, sed/awk, редакторах, языках. Диалекты: базовые (BRE), расширенные (ERE, grep -E), Perl-совместимые (PCRE, grep -P\d, \b, ленивость).

Шаблон Значение
. любой символ
* + ? 0+ / 1+ / 0–1 повторов (+,? — ERE)
{2,5} от 2 до 5 повторов (ERE)
^ $ начало / конец строки
[abc] [^abc] один из / любой кроме
[0-9] [a-z] диапазоны
(ab\|cd) группа / альтернатива (ERE)
\d \w \s \b цифра / слово / пробел / граница слова (PCRE)
\. \/ экранировать спецсимвол
\1 обратная ссылка на группу 1

POSIX-классы: [[:digit:]], [[:alpha:]], [[:space:]], [[:alnum:]].

grep -E '^[0-9]{1,3}(\.[0-9]{1,3}){3}$' file   # строки-IP целиком
grep -E 'error|fail|fatal' app.log             # любое из слов
grep -Eo '[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}' file   # вытащить e-mail (-o)
grep -P '\bword\b' file                        # слово по границам (\b)
grep -P '"(\d+)"' -o file                      # PCRE с группой
sed -E 's/[0-9]+/N/g' file                     # заменить все числа на N
sed -E 's/(\w+)@(\w+)/\2 \1/' file             # перестановка через группы \1 \2
grep -P 'href="(.*?)"' -o file                 # ленивый .*? (PCRE) — до первой "

.* жадный — берёт максимум. Для «до ближайшего» — сузь класс ([^"]*) или ленивый квантор .*? (только PCRE, grep -P/perl):

echo '<a><b>' | grep -Po '<.*?>'   # <a> и <b> по отдельности (ленивый)
echo '<a><b>' | grep -Eo '<.*>'    # <a><b> целиком (жадный)

Группы ( ) захватывают для обратных ссылок (\1) и замен (sed 's/(..)/[\1]/'). Незахватывающая группа в PCRE — (?:...).

+, ?, {}, | не работают в grep

Это ERE — включи grep -E (или экранируй \+ в BRE). Проще всегда grep -E.

\d, \b, ленивость не работают

Это PCRE — нужен grep -P (или perl/python). BRE/ERE их не знают; вместо \d[0-9] или [[:digit:]].

Точка ловит всё подряд

. — любой символ. Для именно точки экранируй: \. (IP/домены).

Спецсимволы шаблона ищутся как regex

Нужен буквальный текст — grep -F (фиксированная строка), без regex.

.  любой   *  0+   +  1+(-E)   ?  0/1(-E)   {2,5} повторы(-E)
^  начало  $  конец   [abc]/[^abc] класс   (a|b) альтернатива(-E)
\d \w \s \b  (-P)     \.  буквально точка     \1  обратная ссылка
grep -E расширенные · grep -P PCRE(\d,ленивость) · grep -F буквально · -o только совпадение

См. также