Перейти к основному содержимому
01ОТДЕЛЬНЫЕ ТЕМЫ · ГЛАВА 01Регулярные выражения для grep404error

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

Прочитано 0%Квизы 0/3Тренажёры 0/2Уровень 1 · Новичок

Зачем это нужно

В главе про терминал мы обходились командами над файлами целиком: показать, скопировать, удалить. Но на чемпионате и в работе постоянно нужна операция потоньше — найти в большом файле нужные строки. Лог веб-сервера на десять тысяч строк, в котором нужно выловить только ошибки. Конфиг, в котором нужно найти строку с портом. Чужой проект, в котором нужно понять, где вообще используется функция с таким-то именем. Листать глазами — не вариант; для этого есть grep.

grep расшифровывается как global regular expression print — «напечатать по глобальному регулярному выражению». Название выдаёт главное: сила grep не в поиске точного текста (это он тоже умеет), а в поиске по шаблону — регулярному выражению (regular expression, коротко regex). Шаблон описывает не конкретную строку, а правило: «строка, начинающаяся с цифры», «слово error в любом регистре», «три цифры, дефис, ещё две цифры». Один раз научившись читать и писать такие правила, ты получаешь суперспособность, которая работает далеко за пределами grep: те же регулярные выражения понимают редакторы кода, языки программирования и половина инструментов командной строки.

Эта страница — углубление: базовый маршрут от неё не зависит, но перед ней стоит пройти главу «Linux и терминал», чтобы команды, флаги и конвейер | уже не были новостью.

grep без регулярок: точный текст и главные флаги

Начнём с того, что regex ещё не требует. В простейшей форме grep получает текст для поиска и файл — и печатает все строки, в которых этот текст встречается:

grep error app.log
GREP · ИДЁТ ПО СТРОКАМ ОДНА ЗА ДРУГОЙшаблон: errorapp.log2026-01-02 INFO start2026-01-02 INFO ready2026-01-03 error: timeout2026-01-04 INFO ok2026-01-05 INFO doneнапечатано:…error: timeoutgrep сравнивает с шаблоном каждую строку отдельно — совпавшую печатает, остальные молча пропускает
Grep сравнивает с шаблоном каждую строку файла отдельно — совпавшую печатает, остальные молча пропускает.

Наведи курсор на части команды посложнее — с флагами, которые понадобятся в первую очередь:

Нажми на часть выражения

Флаги, без которых не живёт ни один день с grep:

  • -i — игнорировать регистр. Ошибки в логах пишут кто во что горазд: Error, ERROR, error — с -i найдутся все.
  • -n — показывать номера строк. Нашёл строку — сразу знаешь, куда идти в редакторе.
  • -vинвертировать поиск: напечатать строки, где шаблона нет. grep -v '#' config.txt — конфиг без строк с решёткой.
  • -c — не печатать строки, а посчитать их: grep -c error app.log ответит одним числом.
  • -w — искать только целые слова: grep -w log найдёт log, но не login и не catalog.
  • -r — искать рекурсивно по всем файлам каталога: grep -r TODO src/ — все заметки TODO во всём проекте.

И приём из главы про терминал: grep умеет читать не только файлы, но и вывод другой команды через конвейер — cat app.log | grep error даёт тот же результат, а history | grep ssh найдёт все команды ssh, которые ты набирал.

Отвечено вопросов: 0 из 4
Чем grep -w error отличается от grep error?
Нужно увидеть конфиг БЕЗ строк-комментариев (в них есть символ #). Какая команда подойдёт?
Что напечатает grep -c error app.log?
Как найти все упоминания TODO во всех файлах проекта сразу?
Отвечено верно: 0 из 4

Точка, экранирование и классы символов

Теперь сама магия. В регулярном выражении часть символов — не буквы, а операторы. Первый из них — точка: . означает «ровно один любой символ». Шаблон v.sion найдёт и vision, и version... стоп, нет: version не найдёт — между v и sion там два символа. А вот v..sion — найдёт version, потому что двум точкам соответствуют er.

Отсюда сразу неприятный сюрприз: если искать точку буквально — например, версию 1.5 или расширение .txt — шаблон 1.5 найдёт заодно 105, 1x5 и вообще «1, что угодно, 5». Чтобы оператор снова стал обычным символом, его экранируют обратной косой чертой: 1\.5 — это уже строго «единица, точка, пятёрка».

Второй оператор — класс символов: квадратные скобки со списком допустимых символов внутри. [abc] — «один символ: a, b или c». Внутри класса работает диапазон через дефис: [0-9] — любая цифра, [a-z] — любая строчная латинская буква, [A-Za-z0-9] — буква или цифра. А если первый символ в скобках — крышка, класс инвертируется: [^0-9] — «один любой символ, кроме цифры».

ТОЧКА И КЛАССЫ СИМВОЛОВ.любой один символсоответствует: v, 1, ?\.буквально точкасоответствует: только .[0-9]один символ из наборасоответствует: 0…9[^0-9]НЕ из наборасоответствует: a, !, _точка без экрана — оператор; с обратной косой — обычный символ; крышка первой в скобках — инверсия
Точка без экрана — любой символ; с обратной косой — буквально точка; квадратные скобки задают набор, крышка первой — инверсию.
Нажми на часть выражения

Обрати внимание на кавычки вокруг шаблона. Символы *, [, ], $ — операторы не только для grep, но и для самой оболочки bash (вспомни подстановку *.txt из главы про терминал). Одинарные кавычки говорят оболочке: «не трогай, передай как есть». Правило простое: шаблон со спецсимволами — всегда в одинарных кавычках; за привычку брать в кавычки вообще любой шаблон никто не осудит.

Якоря: начало и конец строки

По умолчанию grep ищет совпадение где угодно в строке. Якоря (anchors) прибивают шаблон к месту: ^ — к началу строки, $ — к концу.

  • grep '^From' mail.txt — строки, начинающиеся с From; письмо, где From встречается в середине текста, не подойдёт.
  • grep 'done$' tasks.txt — строки, заканчивающиеся на done.
  • grep '^$' file.txt — пустые строки: начало строки, сразу за ним конец, между ними ничего. А grep -c '^$' file.txt их посчитает.
  • grep -v '^#' config.txt — фильтр комментариев поточнее, чем раньше: выкидываются только строки, где # стоит первым символом, а строки, где решётка встречается в середине, остаются.

Якорь — не символ строки, а позиция: ^ не ищет никакую «крышку» в тексте, он утверждает «здесь начало». Поэтому шаблон ^$ находит строку нулевой длины, хотя в нём два символа.

ЯКОРЯ · ПОЗИЦИЯ, А НЕ СИМВОЛgrep '^From' mail.txtFrom: Alice^ — вот здесь, перед первым символомgrep 'done$' tasks.txttask done$ — вот здесь, сразу после последнего^ и $ не совпадают ни с одним символом строки — они утверждают позицию
^ и $ не совпадают ни с одним символом строки — они утверждают позицию: здесь начало, здесь конец.
Отвечено вопросов: 0 из 4
Что найдёт шаблон 1.5 без экранирования?
Что означает класс [^0-9]?
Как найти пустые строки в файле?
Почему шаблон стоит брать в одинарные кавычки?
Отвечено верно: 0 из 4

Квантификаторы: сколько раз повторить

Последний кирпич — квантификаторы (quantifiers), операторы «сколько раз повторяется предыдущий элемент»:

  • * — ноль или больше раз. ab*c найдёт ac, abc, abbbbc.
  • + — один или больше раз. ab+c найдёт abc и abbbc, но уже не ac.
  • ? — ноль или один раз. colou?r найдёт и color, и colour.
  • {n} — ровно n раз, {n,m} — от n до m раз. [0-9]{4} — ровно четыре цифры подряд.

Квантификатор относится к одному предыдущему элементу — символу или классу. [0-9]+ — «одна или больше цифр», а 10* — это «1, а потом сколько угодно нулей» (10, 100, 1000...), не «десять сколько-то раз».

Тонкость, о которую спотыкаются все: исторически у grep два диалекта регулярных выражений. В базовом (BRE — basic regular expressions), который включён по умолчанию, операторы +, ?, {} нужно писать с обратной косой: \+, \?, \{4\}. В расширенном (ERE — extended regular expressions) они работают как есть, но нужен флаг -E. Проще всего запомнить одно правило: пользуешься +, ? или фигурными скобками — добавляй -E и пиши по-человечески.

Нажми на часть выражения
АНАТОМИЯ ШАБЛОНА · ^[0-9]{3}-[0-9]{2}^якорьначало строки[0-9]{3}класс + квантификатортри цифры подряд-литералобычный дефис[0-9]{2}класс + квантификаторещё две цифрыgrep -E '^[0-9]{3}-[0-9]{2}' codes.txt — четыре разных элемента сцепляются в один шаблон
Четыре разных элемента сцепляются в один шаблон: позиция, повторяемый класс, обычный символ, снова класс с повторением.
Отвечено вопросов: 0 из 4
Что найдёт шаблон ab*c?
Чем + отличается от *?
Почему grep '[0-9]{4}' может ничего не найти там, где grep -E '[0-9]{4}' находит?
К чему относится квантификатор в шаблоне 10*?
Отвечено верно: 0 из 4

Практика: grep-квест в терминале

Применим всё в учебном терминале. Честное предупреждение: grep здесь упрощённый — он ищет подстроку и не разбирает регулярные выражения, так что операторы из этой страницы отрабатывай потом в настоящем терминале. Зато флаги команд, конвейер и сама логика «найди иголку в стоге» — как настоящие.

В файле ~/logs/app.log среди сотни строк спрятана одна со словом ACCESS — в ней написан секретный код. Найди её c помощью grep (или cat app.log | grep ...), прочитай код и создай в домашней папке пустой файл, названный этим кодом: если код apple, то touch found_apple.txt.

Задание: grep-квест: выуди код из logs/app.log и создай файл found_<код>.txt
  • found_cherry.txt
Учебный терминал. Введите help, чтобы увидеть список команд.
student@pgk:~$
Как это устроено под капотом
Никакого настоящего Linux здесь нет: файловая система — обычный JS-объект в памяти браузера, где папка — это вложенный объект, а файл — строка с содержимым. Команды ls, cd, mkdir, rm и остальные — функции, которые читают и меняют этот объект, а cp -r — просто глубокое копирование куска JSON. После каждой команды проверка квеста проходит по требуемым путям и смотрит, существуют ли они в этом дереве. Перезагрузишь страницу — «диск» создастся заново с нуля, так что ломать тут можно безнаказанно.

И закрепи руками написание настоящих шаблонов — с регистром, кавычками и косыми всё должно быть точно до символа:

Цель: точность ≥ 90%

grep -in error app.log

Шпаргалка

ЗаписьЧто означаетПримерНайдёт
abcбуквально этот текстgrep error logстроки со словом error
.один любой символv..sionversion, но не vision
\.буквально точка1\.51.5, но не 105
[abc], [0-9]один символ из набора/диапазонаv[0-9]v1, v2...
[^0-9]один символ НЕ из набораid[^0-9]idx, но не id7
^, $начало / конец строки^From, done$позиция, не символ
^$пустая строкаgrep -c '^$' fпосчитать пустые
*предыдущий 0+ разab*cac, abc, abbc
+-E)предыдущий 1+ разab+cabc, но не ac
?-E)предыдущий 0–1 разcolou?rcolor и colour
{n}, {n,m}-E)ровно n / от n до m раз[0-9]{4}четыре цифры подряд
-i / -n / -vбез регистра / с номерами / инверсияgrep -inv
-c / -w / -rпосчитать / целые слова / рекурсивноgrep -rw log .
-Eрасширенный диалект EREgrep -E '[0-9]{3}' codes.txtвключай для + ?
Углубиться

Третий диалект: PCRE. Кроме BRE и ERE, у GNU grep есть флаг -P — Perl-совместимые регулярные выражения, самый богатый диалект: сокращения вроде \d (цифра) и \w (символ слова), ленивые квантификаторы, просмотры вперёд-назад. Именно PCRE-подобный синтаксис используют регулярки в Python, JavaScript и большинстве языков. В скриптах, которые должны работать на любой системе, на -P полагаться нельзя — он есть не во всех сборках grep, — но на своей машине это самый удобный режим.

POSIX-классы. Внутри квадратных скобок работают именованные классы: [[:digit:]] — то же, что [0-9], [[:alpha:]] — буквы, [[:space:]] — пробельные символы. Выглядят громоздко, но корректно работают с любыми локалями и алфавитами — в отличие от диапазона [a-z], который про кириллицу ничего не знает.

egrep и fgrep. В старых скриптах встречаются команды egrep (то же, что grep -E) и fgrep (то же, что grep -F — искать буквально, вообще без регулярных выражений). Они объявлены устаревшими: POSIX рекомендует формы с флагами, и новые скрипты стоит писать именно так.

-o — показать только совпадение. Обычно grep печатает строку целиком. Флаг -o печатает только совпавший кусок, каждое совпадение на своей строке: grep -oE '[0-9]+' log.txt вытащит из файла все числа. В связке с wc -l — готовый счётчик совпадений (не строк, как -c, а именно совпадений).

Дальше по теме:

  • GNU Grep Manual — Regular Expressions — официальное руководство: точное описание BRE, ERE и PCRE со всеми операторами
  • man 7 regex — справка по регулярным выражениям POSIX, общая для grep, sed и других утилит

Что должен уметь

  • Искать текст в файле и в выводе другой команды, применяя флаги -i, -n, -v, -c, -w, -r по назначению.
  • Объяснять, почему шаблон берут в одинарные кавычки и что случится без них.
  • Читать и писать шаблоны с точкой, экранированием, классами [...] и инвертированными классами [^...].
  • Прибивать шаблон якорями ^ и $ — в том числе находить пустые строки и строки-комментарии.
  • Пользоваться квантификаторами *, +, ?, {n,m} и знать, когда нужен флаг -E.
  • Отличать диалекты BRE и ERE и объяснять, почему grep '{4}' и grep -E '{4}' ведут себя по-разному.

Куда дальше: проверенные ресурсы

Интересный факт

Имя grep — буквально команда из редактора ed 1970-х: g/re/p, «глобально найти по regular expression и напечатать». Кен Томпсон вынес её в отдельную программу — и она пережила сам редактор на полвека.

Комментарии

Комментарии появятся после настройки. Нужен аккаунт GitHub — вход прямо в виджете выше.