Вопрос или проблема
Многие файлы конфигурации основаны на формате Ключ значение
или Ключ=значение
с одной строкой для каждого из них. Многие пакеты предоставляют файл конфигурации по умолчанию, где эти доступные ключи конфигурации уже записаны с их значением по умолчанию и/или прокомментированы.
Мне интересно, есть ли инструмент, который позволяет изменять такого рода файлы без необходимости открывать интерактивный редактор и который будет более высокого уровня, чем sed
(возможно, основанный на нем).
Это было бы что-то так же простое, как:
$ conftool файл ключ значение
Он бы находил ключ в файле, удалял знак(и) комментария, если таковые имеются, изменял значение и сохранял результат.
Насколько я знаю, нет универсального инструмента для изменения строк конфигурации. Я представляю, что создать такой инструмент было бы трудно, потому что существует так много различных синтаксисов файлов конфигурации.
Если вы хотите изменить конкретное значение в конкретном файле конфигурации, то вы можете написать специализированный инструмент для этой конкретной задачи.
Вот два примера использования sed и awk, чтобы помочь вам начать
Простая команда sed для замены значения ключа для простого синтаксиса ключ значение
$ sed 's/^key2 value2$/key2 newvalue2/' config
пример
$ cat config
key1 value1
key2 value2
key3 value3
$ sed 's/^key2 value2$/key2 newvalue2/' config
key1 value1
key2 newvalue2
key3 value3
Но будьте осторожны: если есть другие строки key2 value2
(возможно, в других секциях файла конфигурации), то все будут заменены. Это трудно предотвратить в sed (возможно, но сложно) и легче в awk. Смотрите ниже пример команды awk, которая учитывает секции.
Объяснение:
Эта команда sed делает примерно следующее:
для каждой строки:
если строка "key2 value2":
напечатать "key2 newvalue2"
Эта команда sed s/шаблон/заменить/
означает: в каждой строке ищите шаблон
, и если он найден, замените его на заменить
. шаблон
может быть обычной строкой или регулярным выражением (regex).
Символы ^
и &
в регулярном выражении называются якорями и означают начало и конец строки соответственно. Без якорей этот шаблон key2 value2
также совпадал бы с этой строкой xkey2 value2x
, и результаты были бы xkey2 newvalue2x
.
Вот несколько примеров того, как мы можем изменить поведение с помощью шаблона.
Так же работает с синтаксисом ключ=значение
$ sed 's/^key2=value2$/key2=newvalue2/' config
Чтобы просто сопоставить ключ независимо от старого значения
$ sed 's/^key2=.*/key2=newvalue2/' config
Чтобы удалить возможный знак комментария
$ sed 's/^#\?key2 value2$/key2 newvalue2/' config
Чтобы увидеть, что что-то изменилось, если вы перенаправите вывод, вы также можете печатать в stderr
$ sed 's/^#\?key2 value2$/key2 newvalue2/ w /dev/stderr' config > newconfig
Вы можете делать многое другое с правильным регулярным выражением. Но это будет другой ответ на другой вопрос.
Вот скрипт awk, который также может обрабатывать секции конфигурации
/^\[section2\]$/ {
print
insection2=1
next
}
insection2 && /^#?key2=value2$/ {
print "key2=newvalue2"
next
}
/^\[.*\]$/ {
insection2=0
}
1
Используйте его так
$ awk -f configer.awk config
пример
$ cat config
[section1]
key1=value1
key2=value2
[section2]
key1=value1
key2=value2
[section3]
key1=value1
key2=value2
$ awk -f configer.awk config
[section1]
key1=value1
key2=value2
[section2]
key1=value1
key2=newvalue2
[section3]
key1=value1
key2=value2
Вы также можете добавить подробный вывод в stderr, чтобы увидеть, что изменилось, если вы перенаправите вывод
insection2 && /^#?key2=value2$/ {
print "key2=newvalue2"
print "измененная строка "NR > "/dev/stderr"
next
}
Краткое объяснение скрипта awk
Первая правило ищет заголовок секции [config2]
. Он установит флаг insection2
в true
Второе правило ищет строку key2=value2
. Но только если флаг insection2
истинный. Он затем напечатает строку с новым значением.
Третье правило ищет любой другой заголовок секции. Он сбросит флаг insection2
в false.
Последнее правило (одинокий 1
) является “правилом по умолчанию”. Он просто напечатает строку без изменений.
В псевдокоде
для каждой строки:
если строка [section2]:
отметьте, что мы находимся в секции2
иначе если мы в секции2 и строка key2=value2:
напечатать измененную строку
иначе если строка - любой другой заголовок секции:
отметьте, что мы больше не в секции2
иначе
напечатать строку без изменений
Если вы используете KDE, есть опция…
kwriteconfig6 --file "$HOME/.config/kwinrc" --group "Plugins" --key "wobblywindowsEnabled" "true"
это работает для любого конфигурационного файла в системе с этим шаблоном… например, файлы systemd:
sudo kwriteconfig6 --file "/usr/lib/systemd/system/sshd.service" --group "Service" --key "Restart" "on-failure"
Ответ или решение
Как редактировать значения в конфигурационных файлах через командную строку
Редактирование конфигурационных файлов в системах Unix/Linux является распространенной задачей, которую часто необходимо выполнять без запуска интерактивного редактора. Это может быть полезно в сценариях автоматизации и управления конфигурациями. В данной статье мы обсудим, как изменить значение конфигурационного файла, основанного на формате Ключ значение
или Ключ=значение
, с использованием командной строки.
Инструменты для редактирования конфигурационных файлов
Среди множества инструментов, предлагаемых для работы с текстовыми файлами, sed (stream editor) и awk являются наиболее популярными. Однако, как упоминается в вопросе, использование sed может быть не всегда удобным, особенно когда необходимо учитывать разные синтаксисы настройки или секции.
Тем не менее, для простых случаев можно использовать следующие команды:
Пример использования sed
-
Замена значения в формате
Ключ=значение
:sed -i 's/^key=value/key=newvalue/' configfile
Здесь
-i
указывает на то, что файл будет изменен на месте, аs/pattern/replacement/
— это команда замены, гдеpattern
— регулярное выражение для поиска строки, аreplacement
— строка для замены. -
Удаление комментариев:
Если ключ может быть закомментирован с помощью символа
#
, то команда будет выглядеть так:sed -i 's/^#\?key=value/key=newvalue/' configfile
Этот пример ищет строки, начинающиеся с возможного комментария (в данном случае
#
), и заменяет их на нужный формат. -
Замена значения без учета текущего значения:
Если необходимо изменить значение, независимо от его текущей установки, можно использовать:
sed -i 's/^key=.*/key=newvalue/' configfile
Этот регулярное выражение ищет строку, которая начинается с
key=
, и заменяет всё, что идёт после знака равенства.
Пример использования awk
Для более сложных случаев, когда требуется учитывать секции в конфигурационных файлах, можно использовать awk
. Пример скрипта awk
, который редактирует конфигурационный файл с учетом секций:
#/^\[section\]$/ {
print
in_section=1
next
}
in_section && /^#?key=value$/ {
print "key=newvalue"
next
}
in_section && /^\[.*\]$/ {
in_section=0
}
1
Этот скрипт проверяет наличие секции и только внутри этой секции заменяет значение ключа. Вы можете вызвать этот скрипт, передав конфигурационный файл как аргумент:
awk -f configer.awk configfile
Альтернативные инструменты
Если вы ищете более высокоуровневые инструменты, обратите внимание на kwriteconfig
, доступный в KDE и позволяющий редактировать конфигурационные файлы. Например:
kwriteconfig --file "$HOME/.config/kwinrc" --group "Plugins" --key "wobblywindowsEnabled" "true"
Или для системных конфигурационных файлов:
sudo kwriteconfig --file "/usr/lib/systemd/system/sshd.service" --group "Service" --key "Restart" "on-failure"
Заключение
В завершение, редактирование конфигурационных файлов через командную строку может быть выполнено с помощью инструментов, как sed
и awk
, которые подходят для различных сценариев. Будьте внимательны к синтаксису и форматированию файла, чтобы избежать ошибок. Выбор правильного инструмента зависит от конкретной задачи и требований к конфигурации.