How to best use SED to comment out a config value while adding a new config value right after it?
I don't know if it's "the best practice", but sed
code for this is relatively simple:
sed '/^foo_option / {s/^/#/; a\
foo_option /new/opt
}' /path/to/conf.file
It solves the example 1. To solve the example 2 you need to replace each occurrence of foo_option
(there are two occurrences, and note the trailing space) with foo_option=
in the sed
code.
Universal code that solves both examples is more complicated because what you append depends on the presence of =
in the old line; therefore you cannot use a
with a fixed string. Try this:
sed '/^foo_option[= ]/ {
h; s/^/#/; p
g; s|\([= ]\).*|\1/new/opt|
}' /path/to/conf.file
The above code uses the original line twice. First it copies the line from the pattern space to the hold space (h
), adds #
in front and prints the pattern space (p
). Next it copies back from the hold space (g
) and places /new/opt
in the right place; this time the pattern space gets printed because sed
(without -n
) prints by default when it's done processing the line (no p
needed).
Notes:
-
I used
|
in the seconds
, not/
, because/new/opt
contains/
. Your attempt withs/^foo_option .*$/foo_option /new/opt/
was invalid, too many/
characters. In general you can use almost any character. -
In your tries you used
^foo_option
inside the pattern ofs
to match the right line; then you needed it in the replacement (as\1
or literalfoo_option
). A better way is to address the line by using a regex match, like I did:/^foo_option /
or so. Then the following command (or{ }
block) does not need to check if it's the right line, you know it is. You can use commands other thans
; ands
often can be simplified greatly. Even in a simple case of adding#
I prefer/^foo_option / s/^/#/
tos/\(^foo_option \)/#\1/
. The former code is more readable and it's the Right Way. -
In regular expressions
*
is greedy, so.*$
(you used it) does not really need$
.