3

Say I want to automatically update my /etc/ntp.conf configuration using sed. Format of ntp.conf allows to define lists by usage same keywords for lines occurred all over the file. For example:

# first block occurrences
server 1.1.1.1
server 2.2.2.2

driftfile /var/lib/ntp/drift

# second block of occurrences
server 3.3.3.3
server 4.4.4.4

Now, I've got updated list of ntp servers, say 5.5.5.5, 6.6.6.6 and 7.7.7.7. As a result I want to get:

# first block occurrences
server 5.5.5.5
server 6.6.6.6
server 7.7.7.7

driftfile /var/lib/ntp/drift

# second block of occurrences

Can I do it with sed? Is it right tool for this problem or should I use something else?

P.S.: commenting out second block (or both) of occurrences could also be an option.

  • Do you need those two distinct blocks, or could sed delete all such lines and then simply append the new ones? – thrig Feb 4 '17 at 16:43
  • Append new lines to the end of file would be trivial solution. But it's desirable for me to put new lines in place of first block because I want to keep automatically updated values close to related comment blocks in configuration files. – reddot Feb 4 '17 at 16:53
0

If you have the new list of servers in a file named list.txt in cwd:

sed '/^server/{x;//!r list.txt
d}' /etc/ntp.conf

or, if you don't want to use a file but rather hardcode the new server names:

sed '/^server/{x;//!c\
server 1\
........\
server n-1\
server n
d}' /etc/ntp.conf

This assumes that there is at least one non-commented server line in your /etc/ntp.conf (also, it will not remove any server lines that are commented out - you can change the regex to include those too). If you wanted to insert those lines even if there were no server entries in original file (and in that case, add the new servers at the end of file) you could do something like:

sed '/^server/{x;//!r list.txt
d}
${x;//!r list.txt
x}' /etc/ntp.conf

or use the same conditions if you prefer using c\ - I'll leave that as an exercise. Keep in mind that when changing lines with c\ all backslashes and embedded newlines have to be escaped with a backslash (as in my example).

  • Sure, if you wanted to edit the file in-place you'd use sed -i ... – don_crissti Feb 4 '17 at 18:20
  • Is it possible to make sed expression also handling case when there is no server entries in original file (i.e. adding new servers at the end)? – reddot Feb 6 '17 at 13:42
  • @reddot - yes, that's not a problem, see my edit – don_crissti Feb 6 '17 at 14:16
0
sed '
/^server/ d
/first block/a\
server 5.5.5.5\
server 6.6.6.6\
server 7.7.7.7
' /etc/ntp.conf

change the first occurence only:

# first block occurrences
server 5.5.5.5
server 6.6.6.6
server 7.7.7.7

driftfile /var/lib/ntp/drift

# second block of occurrences
| improve this answer | |
  • This solution looks nice and readable but relying on comment text is not good. – reddot Feb 6 '17 at 13:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.