Изменение строки в конфиге с помощью sed

Sed эта мощная утилита, которая позволяет обрабатывать текст, здесь же описано изменение строки в конфиге с помощью sed.

Введение

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

Утилита sed позволяет производить фильтрацию, поиск, замену, вставку и удаление строк или частей текста в файлах или потоках данных. Вот несколько примеров её работы.

  • Редактирование строк с помощью регулярных выражений, но без редактирования самого файла. Замена производится с помощью команды s, мы говорим что и на что меняем.
# sed 's/old/new/' file.txt 
  • Предыдущая команда не редактирует файл. Внесение изменений непосредственно в файл производится с помощью опции -i.
# sed -i 's/old/new/' file.txt
  • Поиск и удаление определённых строк, подпадающих под шаблон выполняется с помощью команды d.
# sed '/pattern/d' file.txt
  • Добавление строки после строки, попадающей под шаблон (pattern) выполняется с помощью команды a.
# sed '/pattern/a\New line' file.txt
  • Также есть возможность выполнять несколько команд через опцию -e. Например заменим строки (s) и удалим строки (d).
sed -e 's/foo/bar/' -e '/baz/d' file.txt

Нашей задачей будет поиск и изменение строки в конфиге, то есть значения определённого параметра, с помощью утилиты sed. Делается это примерно так:

# sed -i '/pattern/s/old/new/' example.conf

То есть мы редактируем файл (используем опцию -i). Находим строку по pattern и в строке меняем (команда s) old на new. И вместо строк мы можем использовать регулярные выражения.

Практика

Для начала придумаем тестовый конфиг, например такой:

$ cat <<EOT > example.conf
parameter_1 = 10
parameter_2 = 13
parameter_3 = 133
parameter_4 = 58
parameter_5 = 38
EOT

Теперь с помощью sed закомментируем parameter_3:

$ sed -i '/^parameter_3 =/s/^/# /' example.conf

$ cat example.conf
parameter_1 = 10
parameter_2 = 13
# parameter_3 = 133
parameter_4 = 58
parameter_5 = 38

А чтобы снять комментарий, сделаем так:

$ sed -i '/^# parameter_3 =/s/^# //' example.conf

$ cat example.conf
parameter_1 = 10
parameter_2 = 13
parameter_3 = 133
parameter_4 = 58
parameter_5 = 38

А если мы не знаем, закомментирована строка или нет, а нам нужно в любом случае снять комментарий и выставить значение. Это тоже можно сделать. Для начала вернём комментарий, а затем выполним замену.

$ sed -i '/^parameter_3 =/s/^/# /' example.conf

$ cat example.conf
parameter_1 = 10
parameter_2 = 13
# parameter_3 = 133
parameter_4 = 58
parameter_5 = 38

$ sed -i '/^#\? parameter_3/s/.*/parameter_3 = 199/' example.conf

$ cat example.conf
parameter_1 = 10
parameter_2 = 13
parameter_3 = 199
parameter_4 = 58
parameter_5 = 38

В регулярном выражении ^#\? означает что символ решётки не обязателен.

В комментарии мне подсказали как снять комментарий и выставить значение (если мы не знаем закомментирована ли была строчка или нет.)

$ sed -i '/parameter_3/c parameter_3 = 205' example.conf

Здесь используется команда c (change), которая заменяет всю строку целиком. В отличии от команды s (substitute), которая заменяет только подстроку соответствующую шаблону. То есть мы находим все строки по шаблону parameter_3 и заменяем их все на parameter_3 = 205.

Это всё я проделывал на тестовом конфиге, важно протестировать своё решение перед реальным изменением, для этого вначале выполняйте команды без опции -i. И только если вы уверены в своё решении, то можете писать скрипт или инструкцию с использованием sed -i.


Другие статьи по программированию на bash вы найдёте здесь.

Если понравилась статья, подпишись на мой канал в VK или Telegram.

4 комментария к “Изменение строки в конфиге с помощью sed”

  1. Снять комментарий в любом случае можно проще — заменить строку на новую по шаблону:

    sed -i ‘/parameter_3/c parameter_3 = 199’ example.conf

    Ответить
  2. А как применить команду только к незакомментированной строке?
    Т.к. меняются и описания с примерами:

    # … text
    # … you can set parameter_3=example for …
    # … text
    parameter_3=value1

    замена применится к обеим строкам и в конфиге будет две одинаковые строки

    # … text
    parameter_3=value2
    # … text
    parameter_3=value2

    Ответить
    • в качестве костыля пока просто добавил якорь $ sed -i ‘/^parameter_3/c parameter_3 = 205’ example.conf
      зная, точно формат своего конфига

      Ответить

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