awk script modification

I want the below script to omit every chunk of data that contains a specific hostname.

here's the scenario. i have a configuration file that contains the configuration of several hosts. a sample of this configuration file is this:

define host {
        address                       10.70.40.40
        host_name                     relay-nasty-01.net
        use                           generic-host
}

define host {
        address                       10.70.40.42
        host_name                     relay-nasty-02.net
        use                           generic-host
}

define host {
        address                       10.70.40.43
        host_name                     relay-nasty-03.net
        use                           generic-host
}

The above is the configuration for Three hosts: relay-nasty-01.net, relay-nasty-02.net, relay-nasty-03.net.

now, this configuration data is quite huge, since it contains information for several hosts.

now, i want to scan this configuration file against a list of host names. and if any of the hostname in this list is found in the configuration file, i want information about that host name to be omitted. I want a new configuration file created without the configuration for that host name(s).

so for example, if relay-nasty-02.net was in the list of hostnames i want to remove from the configuration file, i want a script that will scan the configuration and output EVERYTHING ELSE BUT the configuration for relay-nasty-02.net.

below is a script i was working on. but i dont know how to modify it to do what i specified above.

awk 'BEGIN {
  while((getline < "/tmp/host_list.txt")>0)
     S[$0]

  FS="\n"; RS="}\n"; ORS="}\n";
}

/define host/ {

  for(X in D) delete D[X];

  for(N=2; N<=NF; N++)
  {
       split($N, A, " ");
       D[A[1]]=A[2];
  }

  if (D["host_name"] in S)
       printf("%s -------- %s -------- %s\n", D["host_name"]" " " ", D["address"], D["_secondary_address"])

}' /tmp/hosts.conf

so basically, i would like to modify this script to make it so, when i scan it against the configuration file, it will omit the configuration setup of the host(s) in the list i give it.

so in my example, if i run this script, it should only output the below, because relay-nasty-02.net was in the list of hosts i gave it.

define host {
        address                       10.70.40.40
        host_name                     relay-nasty-01.net
        use                           generic-host
}


define host {
        address                       10.70.40.43
        host_name                     relay-nasty-03.net
        use                           generic-host
}

OS: linux/sun
shell: bash

awk 'FNR==NR{a[$0]=1;next}
{
for(i in a)
 if(index($0,i))
  next
}1' hostlist RS= conf

Change ORS suitably if required.

1 Like

This will do for your single example:

awk 'BEGIN {RS="}";ORS=RS} !/relay-nasty-02.net/ {print}' config_file

How do you transmit the list of host names? In a file, in an array, ...?

this seems to work but it removes configuration for other hosts not in the list. and what do you mean by ORS?

---------- Post updated at 10:18 AM ---------- Previous update was at 09:55 AM ----------

this one here seems like it could work even better.

the problem is, i have a list of host names.

what is the most efficient/fastest way to run that list against the configuration file?

i was thinking something like this but i'm sure it can be done faster in awk:

cat hostlist | while read line 

do

awk 'BEGIN {RS="}";ORS=RS} !/host_name.*${line}/ {print}' config_file

done

How do you mean? Please elaborate with the input (contents of the 2 files) and the output generated by the command.

i wish i could post more information than i already did but i cant.

do you know how to modify the below command to take in a file and read the file for the host lists, instead of specifying the host as it is below?

awk 'BEGIN {RS="}";ORS=RS} !/relay-nasty-02.net/ {print}' config_file

---------- Post updated at 10:52 AM ---------- Previous update was at 10:52 AM ----------

i want to transmit the list of host names in a file. how do i do that?

This won't work as it will scan the entire conf_file as many times as you have lines in your host file thus giving multiple output.

Even though elixir_sinari's proposal works for me, you may want to try this one:

awk 'NR==FNR {a[$0]; next}; !($7 in a) {print $0 RS}' host_file RS="}\n"  conf_file

this didn't work. i'm guessing the problem is with the $7??

Any output? Pls. provide input and output files. I can only test my proposals with mawk 1.3.3
You can try this:

 awk 'NR==FNR {a=(a?a"|":"")$0; next}; !match ($0,a) {print $0 RS}' t1 RS="}\n" test
1 Like

most awk's don't support multi-character definitions for RS or ORS...

OK, thanks vgersh99. Then try to fallback to elixir_sinari's RS= (empty) proposal. But it may lose the empty line between configurations.

the configuration file is in the first post of this thread.

the host list file will contain one host per line, .i.e.:

relay-nasty-01.net
relay-nasty-02.net
relay-nasty-03.net

thank you

Sorry, I left my test files in. Pls. issue

awk 'NR==FNR {a=(a?a"|":"")$0; next}; !match ($0,a) {print $0 RS}' host_file RS="}\n" conf_file

Yes, I tested with your sample files; the result is as desired. You may have to adapt our proposals to your awk version.

1 Like