Paul Neuwirth
Paul Neuwirth

Reputation: 31

sed Remove lines between two patterns (excluding end pattern)

given text like

_adsp           TXT "dkim=all"
VVKMU6SE3C2MF88BG4DJQAECMR9SIIF0 NSEC3 1 1 10 C4F407437E8EA4C5 (
                175MCHR31K25LP89OVJI5LCE0JA2N2AP
                A MX TXT AAAA RRSIG SPF )
            RRSIG   NSEC3 7 3 1800 (
                20200429171433 20200330161758 11672 example.com
                H3l26qmtkuiFZCeSYCCAo5krFE3gjM0I8UeQ9jhj3STy
                X6fM0YizCHEuv4VZynOJGJc1XJnHRHI+p7yLlZ+OVseK
                UfIkPVP+VOmlerwozEpM+Tnt8evwnMTDbcn0zxf/6YJx
                kZeO2AszWkRZ0bctqW7INYo8YuyyuTSxSr8se27fiaPA
                4GXQymepGgv/JGqargzHbyhhkDhENmNo7Qwkjl+a0kI4
                6qqKcEWCsDvnlYUQiDFzc5oRs2j7TT9uybTfwUDQxV+t
                MQFMhzu7LNbRIUuOb16sAEGSdl9mWQ4sZRJ9wuXJWbso
                G+3tY0pBbq4ffScz/JKcrJ0qAuBF1F5JcQ== )
$TTL 1800

I want to get rid by the part with the "(not beginning with whitespace) NSEC3 " until the first line not beginning with a whitespace character.
resulting

_adsp           TXT "dkim=all"
$TTL 1800

in the example.
I tried sed '/^[^\s].*\sNSEC3\s/,/^[^\s]/d;' filename but that doesn't work as expected, example results in

_adsp           TXT "dkim=all"
                H3l26qmtkuiFZCeSYCCAo5krFE3gjM0I8UeQ9jhj3STy
                X6fM0YizCHEuv4VZynOJGJc1XJnHRHI+p7yLlZ+OVseK
                UfIkPVP+VOmlerwozEpM+Tnt8evwnMTDbcn0zxf/6YJx
                kZeO2AszWkRZ0bctqW7INYo8YuyyuTSxSr8se27fiaPA
                4GXQymepGgv/JGqargzHbyhhkDhENmNo7Qwkjl+a0kI4
                6qqKcEWCsDvnlYUQiDFzc5oRs2j7TT9uybTfwUDQxV+t
                MQFMhzu7LNbRIUuOb16sAEGSdl9mWQ4sZRJ9wuXJWbso
                G+3tY0pBbq4ffScz/JKcrJ0qAuBF1F5JcQ== )
$TTL 1800

so resuming printout way too early?

what do I miss?

thank you

P.S.: you maybe see what I want to do is removing DNSSEC parts out of an named zone. didn't find any other way to remove RRSIG and NSEC3 entries, yet. If someone has an idea, I would appreciate that too.

Upvotes: 1

Views: 213

Answers (2)

potong
potong

Reputation: 58478

This might work for you (GNU sed):

sed -n '/^\S.*NSEC/{:a;n;/^\S/!ba};p' file

Turn off implicit printing by using the -n option.

Throw away lines between one starting with a non-space and containing the string NSEC and any lines not starting with a non-space.

Print all other lines.

Alternative:

sed '/^\S.*NSEC/,/^\S/{/^\S.*NSEC\|^\s/d}' file

Yet another alternative:

sed '/^\S.*NSEC/{:a;N;/\n\S/!ba;s/.*\n//}' file

And another:

sed '/^\S.*NSEC/{:a;N;/\n\S/!s/\n//;ta;D}' file

N.B. The first two solutions will delete lines regardless of a line delimiting the end of the deletions. Whereas the last two solutions will only delete lines if there is a line delimiting the end of the deletions.

Upvotes: 0

KamilCuk
KamilCuk

Reputation: 141523

[\s] matches a literal \ or s characters. It doesn't match whitespace.

The /^[^\s]/d; (if [\s] would work as you expect) will also include removing the last line with non-leading whitespaces. I think you have to loop manually.

On the example you've given, the following seems to work:

sed -n '/^[^ \t].*\sNSEC3\s/{ :a; n; /^[^ \t]/bb; ba}; :b; p'

Upvotes: 1

Related Questions