DEV Community

Miro
Miro

Posted on

SED - Update line that starts with but does not contain

I wanted to update my docker.service file to include tls certificates in the start command. The idea was to search for the line that starts with ExecStart= but also not to change anything if that line already contains tcp header -H tcp://. It turned out to be a bit more complicated than expected.

Result

sed -i '\|^ExecStart=.*-H tcp://|! s|^ExecStart=.*|\0 -H tcp://0.0.0.0:2376 --tlsverify --tlscacert='$PWD'/ca.pem --tlscert='$PWD'/server.pem --tlskey='$PWD'/server.key|' /lib/systemd/system/docker.service

Broken in multiple lines for readability

sed -i '\|^ExecStart=.*-H tcp://|!
        s|^ExecStart=.*|\0 -H tcp://0.0.0.0:2376 --tlsverify
        --tlscacert='$PWD'/ca.pem --tlscert='$PWD'/server.pem
        --tlskey='$PWD'/server.key|' /lib/systemd/system/docker.service

In a nutshell, it excludes all lines that start with ExecStart= and contain -H tcp:// and out of remaining lines, if a line starts with ExecStart=, it appends additional arguments to the end of the line.

Explanation

sed -i means that we will change a file in place.

\|A|! s|S|R| - using pipes instead of slashes makes it easier when dealing with paths. Note that syntax starts with a backslash when using special delimiters with addresses (A part).
Using standard slashes would be like /A/! s/S/R/, without leading backslash.

\|^ExecStart=.*-H tcp://|! - using the addresses in sed, exclude lines that start with ExecStart= and have -H tcp:// down the line.

s|^ExecStart=.*|\0 -H tcp://0.0.0.0:2376 ... - search for a line that starts with ExecStart= and grab the rest of the line using .* . In the replace part, \0 will hold the complete line match and the rest is additional text that is appended to the line.

/lib/systemd/system/docker.service - file that is being edited

Conclusion

For a single line change, a file can be checked if the update is actually required before updating it, and then the exclusion part is not needed at all. But if there are more lines that require similar update this could do the trick.

Top comments (0)