sed в bash: регулярные выражения и экранирование без боли

Владислав Павлович

Владислав Павлович

12 января 2026 • 4 мин чтения • 103

Недавно была неприятная проблема. Горело. Почитал. Решил поделиться.


Регулярные выражения в sed: BRE vs ERE

sed по умолчанию использует BRE (Basic Regular Expressions — базовые регулярные выражения по стандарту POSIX).

Что это означает на практике: скобки (){} нужно экранировать, если хочешь использовать их как спецсимволы регэкспа (группа, квантификатор). Без экранирования они воспринимаются как обычные символы.

Специальное значение в BRE имеют только:

text
$.*[\]^

Чтобы использовать их как литералы — экранируй через \. А вот ?, +, | в BRE вообще нет.

Это контринтуитивно: чтобы () стали спецсимволами — их надо экранировать, а чтобы $ стал обычным символом — тоже экранировать. Логики немного, зато традиций хоть отбавляй.

Флаг -r спасает

К счастью, у sed есть ключ -r, который включает ERE (Extended Regular Expressions — расширенные регулярные выражения).

В ERE:

  • (){} работают как спецсимволы без экранирования
  • Появляются +, ?, |
  • Обратные ссылки \1, \2 и т.д. в строке замены (правая часть) — работают
  • & в строке замены — ссылается на всё найденное совпадение целиком

Большинство руководств, онлайн-парсеров и туториалов используют синтаксис ERE — поэтому его и стоит запоминать как основной.

Про PCRE: есть ещё перловые регулярки (PCRE), говорят — огонь. Но для базового использования в шелле их синтаксис совпадает с ERE, так что разница несущественна.


Экранирование в bash

Вот где начинается настоящее веселье. Мы используем sed внутри bash, а у bash есть собственные спецсимволы, которые он интерпретирует ещё до того, как команда вообще до sed доберётся.

В bash три вида экранирования:

1. Побуквенное (обратный слеш)

Берём список спецсимволов bash:

text
# & * ? [ ] ( ) = | ^ ; < > ` $ " ' \

И ставим перед каждым \, если хотим его как литерал. Неудобно для длинных строк, зато универсально.

2. Слабое экранирование — двойные кавычки "

Отключает все спецсимволы кроме $, `, \. То есть переменные шелла ($VAR) и подстановки команд (`cmd`) внутри двойных кавычек всё ещё работают.

3. Сильное экранирование — одинарные кавычки '

Отключает всё. Буквально всё — никакой интерпретации. Единственное ограничение: одинарную кавычку внутри одинарных кавычек не вставить (ведь она завершает строку).


Главное правило: какие кавычки использовать с sed

text
┌─────────────────────────────────────────────────────┐
│  Нет переменных шелла, нет одинарных кавычек в паттерне?
│  → sed -r '...'   (одинарные кавычки, ERE)
│
│  Нужна переменная $VAR или одинарная кавычка в паттерне?
│  → sed -r "..."   (двойные кавычки, ERE)
└─────────────────────────────────────────────────────┘

Повторим ещё раз:

bash
# Стандартный случай — одинарные кавычки
sed -r 's/foo (bar)/\1/'

# Нужна переменная или одинарная кавычка в паттерне — двойные
sed -r "s/foo/$VAR/"

Шпаргалка: BRE vs ERE

Возможность BRE ERE (-r)
Группа \( \) ( )
Квантификатор \{ \} { }
Один или больше ✗ +
Ноль или один ✗ ?
Альтернатива ✗ |
Обратные ссылки в замене \1 \1

Полезные флаги и команды sed

bash
# Замена первого вхождения в каждой строке
sed -r 's/foo/bar/'

# Замена всех вхождений (флаг g)
sed -r 's/foo/bar/g'

# Изменить файл на месте (флаг -i)
sed -r -i 's/foo/bar/g' file.txt

# Разделитель можно менять — удобно если в паттерне есть /
sed 's~foo/bar~baz~'
sed 's|foo/bar|baz|'

Список литературы


Комментарии (0)

Оставить комментарий

Комментариев пока нет. Будьте первым!