Изменение строки в конфиге с помощью 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.
Если понравилась статья, подпишись на мой канал в VK или Telegram .