5

Many configuration files are based on the format Key value or Key=value with one line for each of them. Many packages provide a default configuration file where theses available configuration keys are already written with their default value and/or are commented.

I'm wondering if there is a tool that allows to change that kind of files without the need to open an interactive editor and more high level than sed (possibly built over it).

That would be something as simple as :

$ conftool file key value

It would find the key in the file, remove the comment sign(s) if any, change the value and save the result.

1 Answer 1

3

as far as i know there is no generic config line changer tool. i imagine it would be hard to create such a tool because there are so many different config file syntaxes.

if you want to change a specific value in a specific config file then you can write a specialized tool for that specific task.

here are two examples using sed and awk to help you get started

a simple sed command to replace the value of a key for a simple key value syntax

$ sed 's/^key2 value2$/key2 newvalue2/' config 

example

$ cat config 
key1 value1
key2 value2
key3 value3

$ sed 's/^key2 value2$/key2 newvalue2/' config 
key1 value1
key2 newvalue2
key3 value3

but beware: if there are more key2 value2 lines (possibly in other sections of the config file) then all will be replaced. this is hard to prevent in sed (possible but hard) and easier in awk. see below for an awk command that respects sections.

explanation:

this sed command does roughly the following:

for every line:
  if line is "key2 value2":
    print "key2 newvalue2"

this sed command s/pattern/replace/ means: in every line search for pattern and if found replace with replace. pattern can be a normal string or a regex (regular expression).

the ^ and & in the regex are called anchors and means beginning of line and end of line respectively. without the anchors this pattern key2 value2 would also match this line xkey2 value2x and the results would be xkey2 newvalue2x.

here are some examples how we can change the behaviour with the pattern.

also works with key=value syntax

$ sed 's/^key2=value2$/key2=newvalue2/' config 

to just match key regardless of old value

$ sed 's/^key2=.*/key2=newvalue2/' config 

to remove possible comment sign

$ sed 's/^#\?key2 value2$/key2 newvalue2/' config 

to see that something was changed if you redirect the output you can also print to stderr

$ sed 's/^#\?key2 value2$/key2 newvalue2/ w /dev/stderr' config > newconfig

you can do a lot more with the correct regex. but that would be another answer for another question.

here is an awk script that can also handle config sections

/^\[section2\]$/ {
  print
  insection2=1
  next
}
insection2 && /^#?key2=value2$/ {
  print "key2=newvalue2"
  next
}
/^\[.*\]$/ {
  insection2=0
}
1

use like this

$ awk -f configer.awk config

example

$ 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

you can also add a verbose output to stderr so you can see what has changed if you redirect the output

insection2 && /^#?key2=value2$/ {
  print "key2=newvalue2"
  print "changed line "NR > "/dev/stderr"
  next
}

short explanation of awk script

the first rule looks for the [config2] section header. it will set the insection2 flag to true

the second rule looks for the key2=value2 line. but only if the insection2 flag is true. it will then print the line with the new value.

the third rule looks for any other section header. it will reset the insection2 flag to false.

the last rule (the lone 1) is the "default rule". it will just print the line unchanged.

in pseudo code

for every line:
  if line is [section2]:
    note that we are in section2
  else if we are in section2 and line is key2=value2:
    print modified line
  else if line is any other section header:
    note that we are no longer in section2
  else
    print line unchanged
2
  • For the sed commands, add some line anchors or word boundaries: this code will match oldkey2=value2345 and replace oldkey2=newvalue2345 Mar 29, 2021 at 12:49
  • thank you for pointing that out. i anchored all the regexes.
    – Lesmana
    Mar 29, 2021 at 13:01

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .