Командная строка для редактирования значения конфигурационного файла без интерактивного редактора

Вопрос или проблема

Многие файлы конфигурации основаны на формате Ключ значение или Ключ=значение с одной строкой для каждого из них. Многие пакеты предоставляют файл конфигурации по умолчанию, где эти доступные ключи конфигурации уже записаны с их значением по умолчанию и/или прокомментированы.

Мне интересно, есть ли инструмент, который позволяет изменять такого рода файлы без необходимости открывать интерактивный редактор и который будет более высокого уровня, чем 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
  1. Замена значения в формате Ключ=значение:

    sed -i 's/^key=value/key=newvalue/' configfile

    Здесь -i указывает на то, что файл будет изменен на месте, а s/pattern/replacement/ — это команда замены, где pattern — регулярное выражение для поиска строки, а replacement — строка для замены.

  2. Удаление комментариев:

    Если ключ может быть закомментирован с помощью символа #, то команда будет выглядеть так:

    sed -i 's/^#\?key=value/key=newvalue/' configfile

    Этот пример ищет строки, начинающиеся с возможного комментария (в данном случае #), и заменяет их на нужный формат.

  3. Замена значения без учета текущего значения:

    Если необходимо изменить значение, независимо от его текущей установки, можно использовать:

    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, которые подходят для различных сценариев. Будьте внимательны к синтаксису и форматированию файла, чтобы избежать ошибок. Выбор правильного инструмента зависит от конкретной задачи и требований к конфигурации.

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

Капча загружается...