I am trying to do something that should be simple and routine. I want to search the file /etc/dhcpcd.conf and change an uncommented static ip address assigned to eth0. The sample test file is shown here:
interface eth0
# test variants of comments
#static ip_address=192.168.21.40/24
# static ip_address=192.168.21.40/24
 #static ip_address=192.168.21.40/24
 # static ip_address=192.168.21.40/24
#the line to match and change
static ip_address=123.223.122.005/24
I attempted to implement a solution here: here’s a much-less-cryptic way of doing it in awk answered by Scott - Слава Україні
I chose the AWK solution because it is easy to read however, I have not been able to modify the answer to work for me.  I haven't used sed or awk before so I wrote a test script.
#!/bin/bash
# testing on a copy of the config file
conf_file="/home/user/dhcpcd.conf"
# BASH variable with fake test ip
new_ip=111.222.123.234
cat "$conf_file" |  awk $'
   /interface /                    { matched=0 }
   /interface eth0/                { matched=1 }
    matched                        { gsub( "^\\s*static ip_address=•*" , "static ip_address=111.222.123.234" ) }
                                   { print }
   '
This AWK script is to find the eth0 stanza, then find static ip_address= any text.
and replace this with static ip_address=111.222.123.234. The exception is for # commented lines.  For testing I have hard coded the test new ip into the AWK script.  I want to use the variable $new_ip.
Initially had a problem with the gsub function.  The •* intended to match any text caused issues because I began using .*.  The manual says gsub uses the character • and not a full-stop. without actually highlighting the need to use Alt-7.  That took me a while to find but that problem is now solved.
The 1st remaining problem I now have is that the new ip is inserted in the line rather that replacing the old ip.    The output is:
 static ip_address=111.222.123.234123.223.122.005/24
So the regex is, or should be, matching the whole line, including the old ip to be replaced, but it isn't.
The 2nd problem I have is that I need awk to use the bash variable new_ip.  I have looked and searched but I cannot find an answer that works.
I think this should work:
cat /home/mimir/dhcpcd.conf |  awk -v sip=$new_ip  $'
   /interface /                    { matched=0 }
   /interface eth0/                { matched=1 }
    matched                        { gsub( "^[:blank:]*static ip_address=•*" , "static ip_address=sip" ) }
                                   { print }
 '
but it doesn't. The output was
static ip_address=sip123.223.122.005/24 so awk didn't recognise sip as a variable.  I am doing something wrong, but I can't see it.  It shouldn't be so difficult to do something so simple.
Any help would be much appreciated.
EDIT No.2: For the benefit of those landing here looking for a solution, this is my working test script:
 #!/bin/bash
#  Test reading and setting of the ip address in /etc/dhcpcd.conf  using AWK
# source /etc/dhcpcd.conf  which always includes the lines:
# interface eth0
#  static ip_address=www.xxx.yyy.zzz
# copy of config file for testing
cfg_file="/home/user/dhcpcd.conf"
# fake test ip
new_ip="114.113.112.111"
awk -i inplace -v sip=$new_ip  $'
   /interface /                    { matched=0 }
   /interface eth0/                { matched=1 }
    matched                        { gsub( "^[[:blank:]]*static ip_address=.*" , "static ip_address="sip ) }
                                   { print }
   ' $cfg_file
exit
This is now working because of a combination of advice received below in the comments. This is an answer, but it is not my answer. It works but is not perfect.
This has some limitations. For a technically better answer, see Ed Morton's answer below.
 
    