sed
Потоковый редактор текста — преобразование строк по шаблонам
Описание
sed (stream editor) — потоковый редактор текста, созданный в 1973–1974 годах в Bell Labs Ли Макмэоном. В отличие от интерактивных редакторов, sed читает текст построчно, применяет к каждой строке набор команд и выводит результат. Это делает его идеальным для трансформации потоков данных в пайпах и автоматического редактирования файлов без открытия в редакторе.
Основная команда sed — замена: s/шаблон/замена/флаги. Шаблон — это регулярное выражение. Помимо замены, sed умеет удалять строки (d), вставлять новые строки (a, i), выводить только совпадающие строки (p), работать с диапазонами строк. sed поддерживает адресацию: команды можно применять только к строкам в определённом диапазоне или совпадающим с regex.
В Linux наиболее распространён GNU sed, расширяющий возможности POSIX-совместимого sed: поддержка \w, \s, \+, нечувствительность к регистру (I), редактирование на месте (-i) с поддержкой бэкапа, режим многострочной обработки.
Синтаксис
- SCRIPT — одна или несколько команд sed
- Основная команда замены:
s/REGEX/REPLACEMENT/FLAGS - Адрес:
N(строка N),N,M(строки N–M),/REGEX/(совпадающие строки),$(последняя) - Разделитель в
sможет быть любым символом:s|/path/|/new/|
Флаги и команды
| Флаг / Команда | Описание | Пример |
|---|---|---|
-n |
Подавить автоматический вывод строк (только явные p) |
sed -n '/pattern/p' file |
-e SCRIPT |
Добавить команду скрипта (для нескольких команд) | sed -e 's/a/A/' -e 's/b/B/' file |
-i[SUFFIX] |
Редактировать файл на месте (inplace); опциональный суффикс для бэкапа | sed -i.bak 's/old/new/g' file |
-f FILE |
Читать скрипт из файла | sed -f rules.sed data.txt |
-E / -r |
Расширенные регулярные выражения (ERE) — не нужно экранировать +, ?, () |
sed -E 's/[0-9]+/NUM/g' file |
s/RE/repl/g |
Команда замены; флаг g — все вхождения в строке |
sed 's/foo/bar/g' file |
s/RE/repl/I |
Флаг I — нечувствительно к регистру (GNU sed) |
sed 's/error/ERR/gI' log |
d |
Удалить текущую строку | sed '/^#/d' config.ini |
p |
Вывести текущую строку (обычно с -n) |
sed -n '5,10p' file |
a TEXT |
Добавить строку TEXT после текущей (append) | sed '/match/a\new line' file |
i TEXT |
Вставить строку TEXT перед текущей (insert) | sed '1i\# Header' file |
q |
Выйти после обработки текущей строки | sed '5q' file |
= |
Вывести номер текущей строки | sed -n '/error/=' log |
& |
В строке замены — ссылка на совпавший текст | sed 's/[0-9]*/[&]/' file |
Паттерны использования
Замена строк в файле на месте
# Замена с бэкапом sed -i.bak 's/localhost/production.server.com/g' config.py # Без бэкапа (GNU sed) sed -i 's/version = "1.0"/version = "2.0"/' setup.py
Удаление строк
# Удалить пустые строки sed '/^$/d' file.txt # Удалить комментарии sed '/^#/d' config.ini sed '/^[[:space:]]*#/d' config.ini # с пробелами # Удалить строки с шаблоном sed '/DEBUG/d' app.log
Извлечение диапазона строк
# Строки 10–20 sed -n '10,20p' file.txt # С первой совпадающей до второй sed -n '/START/,/END/p' file.txt # Первые 5 строк sed '5q' file.txt # аналог head -5
Группы захвата в замене
# Поменять местами два слова
sed -E 's/(\w+) (\w+)/\2 \1/' file
# Обернуть числа в скобки
sed -E 's/([0-9]+)/(\1)/g' file.txt
# Дата из YYYYMMDD в YYYY-MM-DD
sed -E 's/([0-9]{4})([0-9]{2})([0-9]{2})/\1-\2-\3/'
Работа с конфигурационными файлами
# Закомментировать строку sed -i 's/^OPTION=/#OPTION=/' /etc/app.conf # Раскомментировать строку sed -i 's/^#OPTION=/OPTION=/' /etc/app.conf # Изменить значение параметра sed -i 's/^timeout=.*/timeout=30/' config.ini
Несколько команд
# Несколько -e sed -e 's/foo/bar/g' -e 's/baz/qux/g' file # Через точку с запятой sed 's/a/A/g; s/b/B/g' file # Из файла скрипта cat > rules.sed << 'EOF' s/old/new/g /^#/d EOF sed -f rules.sed data.txt
Советы и предупреждения
/, используйте другой разделитель. Например, для работы с путями:
sed 's|/home/user|/home/admin|g' file — удобнее, чем экранировать каждый слэш.
& в строке замены означает «весь совпавший текст»:
sed 's/[0-9]*/(&)/g' — обернёт все числа в скобки без явных групп захвата.
-E для расширенных regex, чтобы не экранировать +, ?, (), |:
sed -E 's/(error|warning)/[\1]/gi'
-i ведёт себя по-разному в GNU sed (Linux) и BSD sed (macOS). На macOS sed -i '' требует пустой строки как аргумента; в Linux sed -i достаточно. Для переносимости: sed -i.bak работает везде.
sed обрабатывает BRE (базовые regex) по умолчанию. В BRE +, ?, (), | требуют экранирования backslash. Используйте -E для более привычного синтаксиса (ERE).