Get multi-line sed not to run if regex is found

Hello, everyone. Thanks for taking the time to read my post.

I have nagios config files for which I'm adding the custom variable _mac_address. I have a sed script that places this variable into an existing file. The problem I'm having is if a line in the file is commented out, I don't want the sed script to run on that line. My thought was some usage of /#/! should tell sed not to function if # is included in a line, but that hasn't worked. Here is my existing mostly functional sed which is nestled inside a bash script so I had to escape things like $ when it meant end of line as opposed to a bash variable:

sed -i -n "
        :a
/address.*${RADIO}\$/! {
        N
        ba
}

{G;s/\$/\t_mac_address\t${ARPMAC}/;}
p
s/^.*\$//

:b
  \$! {
    N
    bb
  }

 s/\n//
  p

" ${NAGIOSFILE}

The three shell variables in the sed script are ${RADIO} which is an IP address, ${BIGMAC} which is the mac address of the IP in ${RADIO}, and ${NAGIOSFILE} which is the file containing the text that sed needs to edit.

If I had this block of text before running this sed script:

define host{
        use             generic-host
        host_name       Hostname
        alias           device of some sort
        address         192.168.10.140
        parents         switch
        hostgroups      radios
        }

This is what it would look like after it:

define host{
        use             generic-host
        host_name       Hostname
        alias           device of some sort
        address         192.168.10.140
        _mac_address    aa:bb:cc:11:22:33
        parents         switch
        hostgroups      radios
        }

The problem happens if I have this set of text initially:

#define host{
#        use             generic-host
#        host_name       Hostname before
#        alias           old device of some sort
#        address         192.168.10.140
#        parents         switch
#        hostgroups      radios
#        }

define host{
        use             generic-host
        host_name       Hostname
        alias           device of some sort
        address         192.168.10.140
        parents         switch
        hostgroups      radios
        }

What I'm looking to have is this:

#define host{
#        use             generic-host
#        host_name       Hostname before
#        alias           old device of some sort
#        address         192.168.10.140
#        parents         switch
#        hostgroups      radios
#        }

define host{
        use             generic-host
        host_name       Hostname
        alias           device of some sort
        address         192.168.10.140
        _mac_address    aa:bb:cc:11:22:33
        parents         switch
        hostgroups      radios
        }

But what I'm getting is:

#define host{
#        use             generic-host
#        host_name       Hostname before
#        alias           old device of some sort
#        address         192.168.10.140
         _mac_address    aa:bb:cc:11:22:33
#        parents         switch
#        hostgroups      radios
#        }

define host{
        use             generic-host
        host_name       Hostname
        alias           device of some sort
        address         192.168.10.140
        parents         switch
        hostgroups      radios
        }

I've tried making changes to the substitution line in sed, such as:

{G;/#/! s/\$/\t_mac_address\t${ARPMAC}/;}
{/#/!;G;s/\$/\t_mac_address\t${ARPMAC}/;}
{G;/#/!s/\$/\t_mac_address\t${ARPMAC}/;}

None of those gave me the desired output.

How can I get the output I'm searching for from my sed script? I'm willing to go to awk if needed, but I'd like to stick with sed and would rather stay away from perl and heavier tools.

Thanks!

Not sure if I correctly understood your problem and its intricacies, but there seems to be quite simple a solution:

sed  "/^#/{p;d}; /address.*${RADIO}\$/ s/\$/\n\t_mac_address\t${ARPMAC}/ " file
#define host{
#        use             generic-host
#        host_name       Hostname before
#        alias           old device of some sort
#        address         192.168.10.140
#        parents         switch
#        hostgroups      radios
#        }

define host{
        use             generic-host
        host_name       Hostname
        alias           device of some sort
        address         192.168.10.140
	_mac_address	aa:bb:cc:11:22:33
        parents         switch
        hostgroups      radios
        }
1 Like

Your solution works perfectly, and is far easier to read than my own, thank you very much!