I’m trying to add a line of text to the middle of a text file in a bash script. Specifically I’m trying add a nameserver to my /etc/resolv.conf file. As it stands, resolv.conf looks like this:
# Generated by NetworkManager domain dhcp.example.com search dhcp.example.com nameserver 10.0.0.1 nameserver 10.0.0.2 nameserver 10.0.0.3
My goal is to add nameserver 127.0.0.1
above all other nameserver lines, but below any text above that. In the end I want to my resolve.conf file to look like this:
# Generated by NetworkManager domain dhcp.example.com search dhcp.example.com nameserver 127.0.0.1 nameserver 10.0.0.1 nameserver 10.0.0.2 nameserver 10.0.0.3
How is this possible via a bash script? Is this something sed or awk can do? Or would creative greping to recreate the file be my best move?
Advertisement
Answer
Here is a solution using sed:
$ sed -n 'H;${x;s/^n//;s/nameserver .*$/nameserver 127.0.0.1n&/;p;}' resolv.conf # Generated by NetworkManager domain dhcp.example.com search dhcp.example.com nameserver 127.0.0.1 nameserver 10.0.0.1 nameserver 10.0.0.2 nameserver 10.0.0.3
How it works: first, suppress the output of sed with the -n
flag. Then, for each line, we append the line to the hold space, separating them with newlines:
H
When we come to the end of the file (addressed by $
) we move the content of the hold space to the pattern space:
x
If the first line in pattern space is blank we replace it with nothing.
s/^n//
Then we replace the first line starting with nameserver
by a line containing nameserver 127.0.0.1
, a new line (Your version of sed
may not support n
, in which case replace the n
with a literal newline) and the original line (represented by &
):
s/nameserver .*$/nameserver 127.0.0.1n&/
Now we just need to print the results:
p