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

Рейтинг: 78.5% · 14 голосов
Полный курс LPIC-1 (экзамены 101-500 и 102-500): архитектура, загрузка, пакеты, команды и текст, ФС и права, шелл-скрипты, пользователи, сервисы, сеть, безопасность. Debian и RHEL.
Ответить
Аватара пользователя
Sergey_Sysadmin
Сообщения: 134
Зарегистрирован: 11 май 2026, 05:31

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

Сообщение Sergey_Sysadmin »

Оглавление курса (41)
  1. Введение в LPIC-1 и как устроен путь администратора
  2. Железо, устройства и модули ядра [101.1]
  3. Загрузка системы: от BIOS до systemd [101.2]
  4. systemd, цели и уровни выполнения [101.3]
  5. План разметки диска и swap [102.1]
  6. Загрузчик GRUB 2 [102.2]
  7. Разделяемые библиотеки [102.3]
  8. Управление пакетами в Debian: dpkg и apt [102.4]
  9. Управление пакетами RPM, DNF и Zypper [102.5]
  10. Linux как гость виртуализации [102.6]
  11. Командная строка Bash [103.1]
  12. Обработка текста фильтрами [103.2]
  13. Базовое управление файлами [103.3]
  14. Потоки, конвейеры и перенаправление [103.4]
  15. Процессы: создание, мониторинг, сигналы [103.5]
  16. Приоритеты выполнения процессов [103.6]
  17. Регулярные выражения [103.7] (вы здесь)
  18. Редактор vi и vim [103.8]
  19. Разделы и создание файловых систем [104.1]
  20. Целостность и обслуживание ФС [104.2]
  21. Монтирование файловых систем [104.3]
  22. Урок 21. Права доступа и владение: rwx, chmod, umask и специальные биты
  23. Жёсткие и символические ссылки
  24. FHS и поиск файлов в системе [104.7]
  25. Окружение и кастомизация оболочки [105.1]
  26. Урок 25. Написание простых bash-скриптов [105.2]
  27. Графика, рабочие столы и доступность
  28. Учётные записи пользователей и групп
  29. Автоматизация задач: cron, at, таймеры [107.2]
  30. Локализация и интернационализация [107.3]
  31. Системное время и синхронизация [108.1]
  32. Системное логирование [108.2]
  33. Основы почтового агента (MTA) [108.3]
  34. Печать и CUPS [108.4]
  35. Основы интернет-протоколов [109.1]
  36. Постоянная конфигурация сети [109.2]
  37. Диагностика сети [109.3]
  38. DNS на стороне клиента [109.4]
  39. Задачи администрирования безопасности [110.1]
  40. Настройка безопасности хоста [110.2]
  41. Шифрование данных: SSH и GnuPG [110.3]
Урок 16. Регулярные выражения [103.7]

Регулярные выражения - это язык описания текстовых шаблонов, и без него администратор слеп. Найти строки с ошибками в логе на гигабайт, выдрать IP из access.log, поправить параметр в десятке конфигов одним проходом sed - всё это про регэкспы. В уроке разберём, чем BRE отличается от ERE, как работают якоря, классы и кванторы, и почему grep, egrep и sed понимают шаблоны по-разному. На экзамене 103.7 эти различия спрашивают прямо, а на проде они экономят часы.

Изображение

Как это работает

Регулярное выражение - это не строка для поиска, а программа для маленькой машины (автомата), которая идёт по тексту слева направо и проверяет, складывается ли шаблон. Большинство символов означают сами себя, но часть символов - метасимволы - имеют особый смысл: точка, звёздочка, скобки, якоря. Если нужен буквальный метасимвол, его экранируют обратным слешем.

Исторически в Unix сложились два диалекта. BRE (Basic Regular Expressions) - старый и консервативный: метасимволы плюс, вопрос, фигурные скобки, круглые скобки и вертикальная черта в нём работают только если их экранировать обратным слешем. ERE (Extended Regular Expressions) - расширенный: те же символы спецсимволичны сами по себе, без слеша. Это главный источник путаницы. grep по умолчанию говорит на BRE, grep -E (бывший egrep) - на ERE, sed без ключа - на BRE, sed -E - на ERE.

Точка означает один любой символ. Звёздочка - повтор предыдущего элемента ноль и более раз, она жадная и хватает максимально длинную строку. Якоря ^ и $ привязывают шаблон к началу и концу строки, они не съедают символов, а лишь обозначают позицию. Квадратные скобки задают класс - набор символов, любой один из которых подойдёт: [abc] это a или b или c, диапазон [a-z] это любая строчная латинская. Внутри класса метасимволы теряют силу, а ^ первым символом инвертирует набор: [^0-9] это всё, кроме цифры.

Группировка в круглых скобках позволяет применить квантор к целому куску и запомнить совпавшее для обратной ссылки. Альтернация (вертикальная черта) - это логическое или между вариантами. В замене sed запомненную группу подставляют как \1, \2 и так далее, а весь матч - амперсандом.

Отдельно стоит запомнить про локаль. Диапазоны вроде [a-z] зависят от переменной LC_COLLATE: в некоторых локалях порядок сортировки перемешивает регистры, и [a-z] неожиданно зацепит не то. Поэтому для предсказуемости либо ставят LC_ALL=C, либо используют POSIX-классы: [[:alpha:]], [[:digit:]], [[:space:]], [[:alnum:]], [[:upper:]], [[:punct:]]. Двойные скобки тут не опечатка: [:digit:] это имя класса, а внешние [ ] - сам класс символов.

Команды и примеры

Поиск строк с ошибками в логе, регистронезависимо, с номерами строк:

Код: Выделить всё

grep -in 'error' /var/log/syslog
BRE против ERE на одном и том же шаблоне. Найти слова cat, car, can - то есть ca плюс один символ:

Код: Выделить всё

# BRE: плюс надо экранировать
grep 'ca.' file.txt

# ERE: один-или-более через голый +
grep -E 'colou?r' file.txt   #找 color и colour
Извлечь IPv4-адреса из лога. Шаблон грубый, но рабочий:

Код: Выделить всё

grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' /var/log/nginx/access.log | sort -u
Ключ -o печатает только совпавшую часть, а не всю строку. Те же фигурные скобки {1,3} в BRE писались бы как \{1,3\}.

POSIX-классы вместо хрупких диапазонов. Строки, начинающиеся с буквы:

Код: Выделить всё

grep '^[[:alpha:]]' /etc/passwd
fgrep ищет фиксированную строку без регэкспов - это grep -F. Полезно, когда в искомом много метасимволов, например точек в версии:

Код: Выделить всё

grep -F '10.0.0.1' hosts   # точка тут буквальная, не метасимвол
Замена в sed. Заменить первое вхождение в каждой строке и глобально все:

Код: Выделить всё

sed 's/foo/bar/' file      # первое в строке
sed 's/foo/bar/g' file     # все в строке
sed -i 's/foo/bar/g' file  # на месте, правит файл
Группы и обратные ссылки. Поменять местами два поля, разделённых двоеточием:

Код: Выделить всё

echo 'имя:значение' | sed -E 's/^([^:]+):(.+)$/\2:\1/'
Раскомментировать строку в конфиге - убрать решётку и пробелы в начале:

Код: Выделить всё

sed -i -E 's/^#[[:space:]]*(PermitRootLogin.*)/\1/' /etc/ssh/sshd_config
Амперсанд - весь найденный текст. Обернуть каждое число в скобки:

Код: Выделить всё

echo 'порт 8080' | sed -E 's/[0-9]+/(&)/g'
Различий между Debian/Ubuntu и RHEL/Fedora тут практически нет: grep и sed одинаковы из пакета GNU coreutils/grep. Помните лишь, что в минимальных образах и в Alpine стоит BusyBox-вариант с урезанным набором, а в скриптах для разных систем безопаснее писать ERE через -E, не полагаясь на \( \).

Частые грабли
  • Путаница BRE/ERE: написали grep 'a+b' и удивляетесь, что не находит a+b как один-или-более. В BRE плюс буквальный, нужен grep -E или a\+b.
  • Жадность звёздочки и .* в sed: шаблон .* хватает до конца строки, и замена съедает больше, чем хотелось. Сужайте через [^x]* или конкретные классы.
  • Незаэкранированная точка в IP и версиях: 10.0.0.1 совпадёт и с 10X0Y0Z1. Для буквальной точки - \. или grep -F.
  • Диапазон [a-Z] невалиден или ловит лишнее из-за локали. Используйте [[:alpha:]] или LC_ALL=C.
  • Якоря в середине: ^ и $ это не символы строки, а позиции. grep 'a$b' не найдёт ничего, потому что после конца строки символов нет.
  • egrep и fgrep объявлены устаревшими в современном GNU grep и печатают предупреждение - пишите grep -E и grep -F.
  • sed -i без бэкапа правит файл необратимо. На проде сначала прогоните без -i и посмотрите вывод, либо sed -i.bak.
Мини-лаба
  • Возьмите свой /var/log (syslog или journalctl --no-pager > log.txt) как полигон.
  • Командой grep с -i и -c посчитайте строки, содержащие fail или error, сравните BRE и ERE-варианты альтернации.
  • Через grep -Eo выдерните все IPv4 и прогоните через sort -u | wc -l - сколько уникальных адресов.
  • Сделайте копию sshd_config и одной командой sed закомментируйте строку с PasswordAuthentication, добавив # в начало.
  • Той же копией поменяйте обратно, сняв комментарий через группу и обратную ссылку \1.
  • Напишите шаблон с POSIX-классом, который вытащит из лога временные метки вида HH:MM:SS.
  • Сравните вывод grep 'a.b' и grep -F 'a.b' на строке a.b и axb - убедитесь в разнице.
Контрольные вопросы
  • Чем отличается обработка символов + ? { } ( ) | в BRE и ERE и какими ключами grep и sed переключаются между ними?
  • Что найдёт шаблон ^[^#] и где это применяют при работе с конфигами?
  • В чём разница между . и [.] внутри регэкспа и когда нужен grep -F?
  • Как в sed сослаться на запомненную группу и на весь найденный фрагмент в строке замены?
  • Почему [[:digit:]] предпочтительнее [0-9] и при чём тут переменная LC_COLLATE?
  • Что делает квантор * применительно к предыдущему элементу и почему он называется жадным?
👍6 ❤️3 🔥2 😄 🤔1
Аватара пользователя
Joeppp
Сообщения: 1
Зарегистрирован: 16 май 2026, 05:39

Re: Регулярные выражения [103.7]

Сообщение Joeppp »

А почему egrep ругается deprecated, его же все юзают? Перешёл на grep -E, и правда предупреждение пропало.
👍 ❤️ 🔥1 😄 🤔
Аватара пользователя
scalaandy
Сообщения: 1
Зарегистрирован: 26 май 2026, 23:22

Re: Регулярные выражения [103.7]

Сообщение scalaandy »

Споткнулся на sed -i без бэкапа, снёс рабочий конфиг. Теперь только sed -i.bak и сначала прогон без -i.
👍3 ❤️ 🔥 😄 🤔1
Ответить
← Предыдущая глава
Приоритеты выполнения процессов [103.6]
Следующая глава →
Редактор vi и vim [103.8]

Все главы курса «LPIC-1: администратор Linux (101 + 102)»

Поделиться темой: ✈ Telegram VK
  • Похожие темы

Вернуться в «LPIC-1: администратор Linux»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость