Linux sed: как заменить строку в файле

Категория: Bash · Язык: Bash · Обновлено:

Чтобы заменить текст в файле, выполните sed -i 's/старое/новое/g' файл. Ключ -i записывает результат прямо в файл, s/// задаёт замену, а флаг g заменяет все совпадения в строке, а не только первое. Без -i результат выводится на экран, файл не меняется.

Основная замена

Bash
sed 's/localhost/db.example.com/' config.txt        # показать результат, файл не меняется
sed -i 's/localhost/db.example.com/g' config.txt    # изменить файл, заменить все вхождения в строке
sed -i.bak 's/debug=true/debug=false/' config.txt   # изменить файл и сохранить копию config.txt.bak

Перед массовой правкой сначала запустите команду без -i и проверьте вывод, либо используйте -i.bak.

macOS отличается

В GNU sed (Linux) запись -i без значения. В BSD sed (macOS) после -i обязателен аргумент:

Bash
sed -i '' 's/old/new/g' file.txt      # macOS
sed -i 's/old/new/g' file.txt         # Linux
sed -i.bak 's/old/new/g' file.txt     # работает в обеих системах

Другой разделитель

Если в тексте есть косые черты, замените разделитель на |, # или ,:

Bash
sed -i 's|/var/www/old|/var/www/new|g' nginx.conf

Замена только в нужных строках

Bash
sed -i '3s/foo/bar/' file.txt                  # только в третьей строке
sed -i '2,4s/foo/bar/g' file.txt               # в строках со второй по четвёртую
sed -i '/^server/s/80/8080/' nginx.conf        # только в строках, начинающихся с server

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

Bash
sed -i -E 's/([0-9]+)\.([0-9]+)/\2.\1/' file.txt      # поменять местами числа: 12.34 -> 34.12
sed -i -E 's/[[:space:]]+$//' file.txt                # убрать пробелы в конце строк
sed -i -E 's/^(.*)$/"\1"/' file.txt                   # обернуть каждую строку в кавычки

Ключ -E включает расширенные регулярные выражения: скобки и + можно писать без обратной косой черты. Группы подставляются как \1, \2.

Удалить и добавить строки

Bash
sed -i '/^#/d' file.txt                        # удалить строки-комментарии
sed -i '/^$/d' file.txt                        # удалить пустые строки
sed -i '1i # Файл создан автоматически' file.txt     # вставить строку перед первой
sed -i '$a # конец файла' file.txt                   # добавить строку в конец

Замена во многих файлах

Bash
grep -rl "old.example.com" ./site | xargs sed -i 's/old.example.com/new.example.com/g'
find . -name "*.conf" -exec sed -i 's/8080/9090/g' {} +

Команда grep -rl выводит только имена файлов с совпадением, поэтому sed обрабатывает лишь нужные файлы.

Специальные символы

Символы ., *, [, ], ^, $, \` и / имеют особое значение. Чтобы заменить их как обычный текст, экранируйте обратной косой чертой: s/1.5/2.0/` заменяет именно «1.5», а не «1 + любой символ + 5».

Частые вопросы

Почему sed не меняет файл?

Вы не указали -i. Без него sed только печатает результат. Перенаправление sed ... file > file не работает, оно обнуляет файл до чтения.

Как заменить без учёта регистра?

Добавьте флаг I в конце: s/error/warn/Ig (GNU sed).

Как использовать переменную оболочки в sed?

Берите команду в двойные кавычки: sed -i "s/old/$NEW/g" file. Следите, чтобы в переменной не было разделителя и специальных символов.