Команда sed: замена строк, удаление строк и использование опции -i

Тестовая средаСемейство RHELAlmaLinux 9.8Учётная запись rootПроверено 2026-10-28

Команда sed — это инструмент Linux, который читает файл строка за строкой и выполняет замену, удаление и вставку, поэтому вы можете менять значения в файле конфигурации, не открывая редактор. Когда мы запустили sed для копии файла wp-config.php WordPress на сервере AlmaLinux 9, удалось изменить имя базы данных, сохранив оригинал с помощью -i.bak.

Сообщения об ошибках в этой статье приведены точно в том виде, в каком они вышли при английской locale.

1️⃣ Основы команды sed и замена через s

Самая востребованная команда s заменяет строки в формате [s/искомая строка/новая строка/]. В строке заменяется только первое совпадение.

echo 'http://example.com http://example.com/blog' | sed 's/http:/https:/'
https://example.com http://example.com/blog

Чтобы заменить все совпадения в строке, добавьте в конец флаг g.

echo 'http://example.com http://example.com/blog' | sed 's/http:/https:/g'
https://example.com https://example.com/blog

Если добавить в конец имя файла, sed прочитает этот файл и выведет изменённый результат. В копии wp-config-sample.php из WordPress под именем wp-config.php мы изменили значение DB_USER и проверили только эту строку через grep.

sed 's/username_here/wp_user/' wp-config.php | grep DB_USER
define( 'DB_USER', 'wp_user' );

Раз значение в выводе изменилось, легко решить, что изменился и файл, но без опций sed только выводит результат на экран и оставляет исходный файл как есть. Когда мы снова нашли ту же строку в файле, в ней осталось первоначальное значение.

grep DB_USER wp-config.php
define( 'DB_USER', 'username_here' );

Чтобы изменить и исходный файл, используйте опцию -i из раздела 4️⃣.

2️⃣ Выбор строк в sed по номеру и шаблону (-n, p)

Без адреса команда s применяется ко всем строкам, поэтому для работы с отдельными строками укажите перед командой номер строки или шаблон как адрес. -n отключает автоматический вывод, а p выводит выбранные строки. Вместе они показывают только строку 23.

sed -n '23p' wp-config.php
define( 'DB_NAME', 'database_name_here' );

Два номера строк через запятую дают этот диапазон. Строки с 23 по 32 — это раздел с настройками имени базы данных, пользователя, пароля и хоста.

sed -n '23,32p' wp-config.php
define( 'DB_NAME', 'database_name_here' );

/** Database username */
define( 'DB_USER', 'username_here' );

/** Database password */
define( 'DB_PASSWORD', 'password_here' );

/** Database hostname */
define( 'DB_HOST', 'localhost' );

Если вместо номера строки написать шаблон между косыми чертами, будут выбраны все строки с этим шаблоном.

sed -n '/DB_/p' wp-config.php
define( 'DB_NAME', 'database_name_here' );
define( 'DB_USER', 'username_here' );
define( 'DB_PASSWORD', 'password_here' );
define( 'DB_HOST', 'localhost' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );

Команда [=] выводит номер выбранной строки. Адрес $ означает последнюю строку, поэтому через [$=] можно узнать общее число строк файла.

sed -n '/DB_HOST/=' wp-config.php
32
sed -n '$=' wp-config.php
102

Адрес можно поставить и перед командой s. Ниже результат замены localhost только в строке 32 с выводом лишь изменённой строки через флаг p.

sed -n '32s/localhost/127.0.0.1/p' wp-config.php
define( 'DB_HOST', '127.0.0.1' );

При запуске p без -n выбранная строка появилась ещё раз. sed читает строки по одной в пространство шаблона, выполняет команды, а затем автоматически выводит пространство шаблона, поэтому строка 2, выведенная через p, снова появляется при автоматическом выводе.

sed '2p' wp-config.php | head -n 4
<?php
/**
/**
 * The base configuration for WordPress

Такая обработка по одной строке похожа на заводской конвейер, который подаёт детали по одной на рабочий стол, обрабатывает их и переходит к следующей.

На схеме ниже можно по шагам сравнить, что выводит каждая команда для каждой строки.

🧭 Пространство шаблона sed и автоматический вывод: p, d в строке 2
Поясняющая схема
⚙️ Команда
$ sed '2p'-n '2p''2d' wp-config.php
Прочитанная строкаВыполнение команды и вывод
Строка 1 → пространство шаблона<?php
➜
Отличается от адреса 2: команды нетАвтоматический вывод 1 разНет вывода из-за -n
Строка 2 → пространство шаблона/**
➜
Совпадает с адресом 2: выполняется pСовпадает с адресом 2: выполняется d1 раз от p + 1 раз автоматическиТолько 1 раз от pОчищает пространство шаблона, переход к следующей строке
Строка 3 → пространство шаблона * The base configuration for WordPress
➜
Отличается от адреса 2: команды нетАвтоматический вывод 1 разНет вывода из-за -n
🖥️ Что выводится на экран (строки 1~3)
<?php/**/** * The base configuration for WordPress
p выводит пространство шаблона ещё раз, поэтому без -n строка 2 появляется дважды.
-n отключает автоматический вывод, поэтому только выбранная через p строка 2 выводится один раз.
d очищает пространство шаблона и переходит к следующей строке, поэтому строка 2 не выводится автоматически.

3️⃣ Удаление и вставка строк командой sed (d, i, a)

d удаляет выбранные строки. Чтобы увидеть пример настройки nginx ниже без строк комментариев, выберите шаблоном [^ *#] строки, которые начинаются с # или содержат перед # только пробелы.

cat example.conf
# example.com
server {
    listen 80;
    server_name example.com www.example.com;

    # document root
    root /var/www/example.com;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}
sed '/^ *#/d' example.conf
server {
    listen 80;
    server_name example.com www.example.com;

    root /var/www/example.com;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

Если соединить команды точкой с запятой, удаляется и [^$], что означает пустую строку. Две пустые строки, оставшиеся после удаления комментариев, исчезли, и остались только строки настроек.

sed '/^ *#/d; /^$/d' example.conf
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.php index.html;
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

i вставляет текст перед выбранной строкой, а a после неё. Результат вставки одной строки комментария перед строкой 1 показан ниже.

sed '1i # managed by sed' example.conf | head -n 3
# managed by sed
# example.com
server {

Легко решить, что текст с отступом после a вставится вместе с отступом, но GNU sed пропускает пробелы сразу после a и вставляет только текст.

sed '/index index.php/a    client_max_body_size 64M;' example.conf
# example.com
server {
    listen 80;
    server_name example.com www.example.com;

    # document root
    root /var/www/example.com;
    index index.php index.html;
client_max_body_size 64M;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

Чтобы сохранить отступ, добавьте после a обратную косую черту. Всё начиная с пробела после неё попадает в текст.

sed '/index index.php/a\    client_max_body_size 64M;' example.conf
# example.com
server {
    listen 80;
    server_name example.com www.example.com;

    # document root
    root /var/www/example.com;
    index index.php index.html;
    client_max_body_size 64M;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

c заменяет выбранную строку целиком. Ниже первые четыре строки результата замены строки listen 80 на 8080.

sed '/listen 80;/c\    listen 8080;' example.conf | head -n 4
# example.com
server {
    listen 8080;
    server_name example.com www.example.com;

4️⃣ Прямое изменение файлов через sed -i и имя резервной копии

-i сохраняет результат в исходный файл, а не выводит на экран. Текст сразу после -i добавляется в конец имени резервной копии. wp-config.php и другие файлы, которые читает сайт, лучше редактировать с -i.bak, сохраняя оригинал.

cp wp-config-sample.php wp-config.php
sed -i.bak 's/database_name_here/wordpress_db/' wp-config.php

С -i на экран ничего не выводится, поэтому проверьте файлы через ls -l.

ls -l wp-config.php*
-rw-r--r-- 1 root root 3333 Oct 28 15:13 wp-config.php
-rw-r--r-- 1 root root 3339 Oct 28 15:13 wp-config.php.bak

Рядом появились отредактированный файл и файл .bak. Размер уменьшился на 6 байт, потому что database_name_here сократилось до wordpress_db. Сравнение двух файлов через diff показывает только изменённую строку.

diff wp-config.php.bak wp-config.php
23c23
< define( 'DB_NAME', 'database_name_here' );
---
> define( 'DB_NAME', 'wordpress_db' );

Изменилась одна строка DB_NAME в строке 23.

Если нужно изменить несколько значений, свяжите скрипты через -e и выполните их за один раз.

sed -i -e 's/username_here/wp_user/' -e 's/password_here/wp_pass/' wp-config.php
grep -n -e DB_USER -e DB_PASSWORD wp-config.php
26:define( 'DB_USER', 'wp_user' );
29:define( 'DB_PASSWORD', 'wp_pass' );

Если написать -i и -e слитно как [-ie], буква e читается как часть имени копии, и, как показано ниже, появился файл wp-config.phpe.

sed -ie 's/127.0.0.1/localhost/' wp-config.php
ls wp-config.php*
wp-config.php
wp-config.php.bak
wp-config.phpe

-i записывает изменённое содержимое в новый файл, а затем переименовывает его в исходное имя, поэтому номер inode файла до и после запуска различается.

ls -i wp-config.php
207618887 wp-config.php
sed -i 's/localhost/127.0.0.1/' wp-config.php
ls -i wp-config.php
207618883 wp-config.php

Номер inode, бывший 207618887 до запуска, сменился на 207618883.

Если файла нет или имя файла пропущено, sed завершается ошибкой ниже и ни один файл не меняется.

sed -i 's/x/y/' no-such.php
sed: can't read no-such.php: No such file or directory
sed -i 's/x/y/'
sed: no input files

5️⃣ Регулярные выражения sed, смена разделителя и опции

🔲 Регулярные выражения и смена разделителя

Если менять значение с косыми чертами, например путь, разделитель команды s смешивается с косыми чертами значения, поэтому перед каждой косой чертой в значении нужна обратная косая черта.

sed -n 's/\/var\/www\/example.com/\/srv\/www\/example.com/p' example.conf
    root /srv/www/example.com;

Символ сразу после s становится разделителем, поэтому если перейти на |, которого нет в значении, тот же результат получится без обратных косых черт.

sed -n 's|/var/www/example.com|/srv/www/example.com|p' example.conf
    root /srv/www/example.com;

Точка (.) в шаблоне соответствует любому одному символу. Ниже результат шаблона для example.com, который изменил и exampleXcom.

echo 'exampleXcom example.com' | sed 's/example.com/test.org/g'
test.org test.org

Чтобы искать точку как символ, поставьте перед ней обратную косую черту.

echo 'exampleXcom example.com' | sed 's/example\.com/test.org/g'
exampleXcom test.org

Часть в скобках вызывается в новой строке через [\1]. С -E скобки и + используются без обратных косых черт. Ниже результат, где число после listen осталось, а default_server добавлено.

sed -nE 's/listen ([0-9]+);/listen \1 default_server;/p' example.conf
    listen 80 default_server;

Без -E тот же скрипт читает скобки как текст, и появляется ошибка, что нет группы для вызова. Чтобы работать без -E, ставьте обратную косую черту перед скобками и +.

sed -n 's/listen ([0-9]+);/listen \1 default_server;/p' example.conf
sed: -e expression #1, char 46: invalid reference \1 on `s' command's RHS
sed -n 's/listen \([0-9]\+\);/listen \1 default_server;/p' example.conf
    listen 80 default_server;

[&] в новой строке означает весь текст, совпавший с шаблоном, поэтому перед совпавшей частью можно добавить # и превратить строку в комментарий.

sed -n 's/server_name .*;/# &/p' example.conf
    # server_name example.com www.example.com;

🔲 Опции команды sed

📌 Основные опции: результаты из этой статьи

ОпцияНазначениеРезультат в этой статье
-nОтключает автоматический вывод и выводит только строки, выбранные через psed -n '23p' показывает только строку 23; без -n 2p выводит строку 2 дважды
-iСохраняет результат в исходный файл вместо экрана (текст сразу после опции идёт в конец имени копии)-i.bak создаёт wp-config.php.bak; после запуска меняется номер inode
-eСвязывает несколько скриптов и выполняет их за один разDB_USER и DB_PASSWORD меняются за один раз; при слитном -ie появляется копия wp-config.phpe
-EИспользует расширенные регулярные выражения (без обратной косой черты у скобок и +)Выводит listen 80 default_server;; тот же скрипт без -E даёт ошибку [invalid reference]
--follow-symlinksВместе с -i редактирует исходный файл, на который указывает ссылкаБез неё на месте ссылки появляется обычный файл, а оригинал не меняется; с ней меняется исходное значение

📎 Другие опции: по официальному руководству

ОпцияНазначение
-fЧитает скрипт из файла и выполняет его
-rРасширенные регулярные выражения, как -E (переносимее -E)
-sОбрабатывает файлы по отдельности, а не как один непрерывный поток
-zРазделяет строки нулевым символом вместо перевода строки
-uЧитает ввод меньшими порциями и чаще сбрасывает вывод
--posixОтключает все расширения GNU
--debugВыводит ход выполнения в развёрнутом виде

🔲 Симулятор команды sed

В рабочей папке симулятора ниже есть копия wp-config.php и example.conf. Вы можете сами вводить изученные команды, а файлы, изменённые через -i, проверять через ls -l и diff.

Симулятор команды sedGNU sed
[root@server work]#
Клавишами ↑↓ можно вызвать ранее введённые команды.

🔢 FAQ & рекомендуемые материалы

В wp-config-sample.php из WordPress концы строк CRLF, поэтому прямо перед концом строки стоит невидимый [\r]. [/false );$/] не вывел ни одной строки, а в копии, где [\r] удалён через [s/\r$//], тот же шаблон нашёл строку WP_DEBUG.

-i создаёт на месте ссылки новый обычный файл и сохраняет в него, поэтому оригинал, на который указывала ссылка, не изменился. Чтобы редактировать исходный файл, укажите также [--follow-symlinks]. Тогда ссылка осталась, а исходное значение изменилось.

Даже заданную через NEW=wp_user переменную оболочка не подставляет внутри одинарных кавычек, и [$NEW] попадает как текст. Когда скрипт заключили в двойные кавычки, оболочка сначала подставила переменную, и на месте [$NEW] оказалось wp_user.

🧭 Рекомендуемые материалы о текстовых командах 9 статей · 2 источника
🗂️ Команды просмотра · редактирования текста
📄 Команда grep 📄 Команда sort 📄 Команда uniq 📄 Команда tee 📄 Команда sed
📄 Команда cat 📄 Команда less 📄 Команды head · tail 📄 Команды vi · vim
Интерфейс командной строки Linux (Linux command line interface, CLI)
Linux · Текст
Команда grep в Linux
Команда grep в Linux служит для поиска нужной строки в текстовых и ASCII-файлах, например в журналах, и часто сочетается с командами tail и find через канал (|).
Читать →Текущая статья
Интерфейс командной строки Linux (Linux command line interface, CLI)
Linux · Текст
Команда sort в Linux: сортировка файлов
Команда sort в Linux, название которой означает вид или классификацию, сортирует содержимое (записи) ASCII-файлов.
Читать →Текущая статья
Интерфейс командной строки Linux (Linux command line interface, CLI)
Linux · Текст
Команда uniq в Linux
Команда uniq в Linux — сокращение от «unique»; она убирает повторяющиеся строки из текстового файла и выводит только одну.
Читать →Текущая статья
Интерфейс командной строки Linux (Linux command line interface, CLI)
Linux · Текст
Команда tee в Linux
Команда tee в Linux названа по аналогии с фитингом в трубопроводе.
Читать →Текущая статья
Поясняющая схема пространства шаблона и автоматического вывода команды sed: с 2p строка 2 выводится дважды
Linux · Текст
Команда sed: замена строк, удаление строк и использование опции -i
Команда sed — это инструмент Linux, который читает файл строка за строкой и выполняет замену, удаление и вставку, поэтому вы можете менять значения в файле конфигурации, не открывая редактор.
Читать →Текущая статья

ℹ️ О партнёрских ссылках
Материалы этого сайта содержат партнёрские ссылки. Если посетитель покупает товар или услугу по такой ссылке, сайт получает комиссию от продавца. При этом сумма, которую платит покупатель (при акционных скидках сумма снижается ↓), не увеличивается. Указанные цены, скидки и наличие актуальны на момент написания и могут отличаться, поэтому перед покупкой уточняйте их у продавца. Товары выбираются и оцениваются по нашим собственным критериям, а комиссия не влияет ни на порядок, ни на содержание обзоров.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Докажите, что вы человек: 2   +   2   =