perun_
perun_

Reputation: 31

sed delete block

Can you help me with deleting some block from dhcp config file using sed. File looks like:

host dev1 {
  host-identifier option agent.circuit-id "test1:418";
  fixed-address xxx.xxx.xxx.xxx;
  option routers xxx.xxx.xxx.xxx;
  option subnet-mask xxx.xxx.xxx.xxx;
}
host host2{
  host-identifier option agent.circuit-id "test2-:5";
  fixed-address xxx.xxx.xxx.xxx;
  option routers xxx.xxx.xxx.xxx;
  option subnet-mask xxx.xxx.xxx.xxx;
}

I should delete block for host matched by circuit-id. I did it by command:

sed -e '/^host\s*\S*\s*{\s*/ { N; /\s*test1:418/ { N; /[^host]/ { N; /[^host]/ { N; /[^host]/ { N; /[^host]/d}}}}}' -e '/^$/d' /path/to/file

But it doesn't seem acceptable at all...:(

Upvotes: 0

Views: 206

Answers (1)

hek2mgl
hek2mgl

Reputation: 158020

If this is an isc dhcp server I strongly recommend to use omshell to modify the config.

Otherwise, if you have GNU gawk, the following gawk command might be good enough for you:

gawk '!/test2-:5/' RS='}\n' ORS='}\n' file
          ^----------------------------------- ID goes here

The command is limited to GNU gawk because it using a multi line record separator.

Explanation:

Using }\n as the record separator, awk will process the file block by block instead the default line-wise mode. Meaning awk will see these records:

host dev1 {
  host-identifier option agent.circuit-id "test1:418";
  fixed-address xxx.xxx.xxx.xxx;
  option routers xxx.xxx.xxx.xxx;
  option subnet-mask xxx.xxx.xxx.xxx;

and

host host2{
  host-identifier option agent.circuit-id "test2-:5";
  fixed-address xxx.xxx.xxx.xxx;
  option routers xxx.xxx.xxx.xxx;
  option subnet-mask xxx.xxx.xxx.xxx;

On those records we apply the regular expression !/test2-:5/. The ! in front negates the match. We don't need to specify more since awk will by default print the current record if the condition evaluates to true. Since the second record matches the pattern it will not get printed.

Using \n} also for the output record separator adds the closing bracket when printing.


Btw, with sed I would use a loop based on a label (:a). We slurp input starting from /host .*{/ until the closing } and append all lines to the pattern buffer. Once the closing } is reached we check if the pattern buffer contains the ID. If it contains the id it will get deleted:

sed '/host .*{/{:a;N;/}/!ba;/test2-:5/d}' file

Upvotes: 1

Related Questions