在我的 OpenDKIM 密钥文件中,我有一些无法放入“正确”DNS 记录的额外引号。(我很惊讶 OpenDKIM 开发人员允许在他们的文件中这样做,但那是另一回事。)
在 RegEx 中,它是两个带空格的双引号,其中包含一个换行符。这是需要删除的模式。
以下是我有:
dkim._domainkey IN TXT ( "v=DKIM1; k=rsa; t=s; s=email; "
"p=MyRidicul0u2e70nGK37pqawrje9vfo34qjfijsfj[o4ijq39408jfaes04fj34q09qj340rf93qw4jfp9q834jfw8934fj3qw4fj" ) ;
我需要删除这些引号和新行以获得以下内容:
dkim._domainkey IN TXT ( "v=DKIM1; k=rsa; t=s; s=email; p=MyRidicul0u2e70nGK37pqawrje9vfo34qjfijsfj[o4ijq39408jfaes04fj34q09qj340rf93qw4jfp9q834jfw8934fj3qw4fj" ) ;
而且,我想用它sed
来做这件事,但awk
仍然欢迎回答。
我最大的努力是这样的:
sed 's/"\s"//' opendkim.txt
答案1
额外的引号不能出现在“正确”的 DNS 记录中。(我很惊讶 OpenDKIM 开发人员允许在他们的文件中这样做,但那是另一回事。)
根据 RFC 1035,这是完全有效的 DNS 记录。TXT 记录由一个组成或者更多“字符串”(每个字符串在区域文件中都以带引号的字符串或不带引号的裸字形式书写),而括号允许在存储在文本格式的区域文件中时跨多行指定记录(请参阅第 35 页)。
这DKIM 规范表示在“_domainkey”TXT 记录中找到的所有字符串都会连接在一起以生成值,因为 DNS 中单个字符串的长度限制为 255 个字节,并且不可能将大小合适的 RSA 密钥放入该限制中。因此,DKIM 公钥跨越多个字符串不仅是正常的,而且实际上是必需的。
如果您的 DNS 服务器系统不接受这一点,那么它对“正确”的定义就很奇怪。
$ cat x.zone
$TTL 1h
@ IN SOA . . 1 1h 1h 1h 1h
@ IN NS .
dkim._domainkey IN TXT ( "v=DKIM1; k=rsa; t=s; s=email; "
"p=MyRidicul0u2e70nGK37pqawrje9vfo34qjfijsfj[o4ijq39408jfaes04fj34q09qj340rf93qw4jfp9q834jfw8934fj3qw4fj" ) ;
$ named-checkzone example.com x.zone
zone example.com/IN: loaded serial 1
OK
$ knot-kzonecheck --verbose x.zone
No semantic error found
$ nsd-checkzone example.com x.zone
zone example.com is ok
$ ldns-read-zone x.zone
dkim._domainkey. 3600 IN TXT "v=DKIM1; k=rsa; t=s; s=email; " "p=MyRidicul0u2e70nGK37pqawrje9vfo34qjfijsfj[o4ijq39408jfaes04fj34q09qj340rf93qw4jfp9q834jfw8934fj3qw4fj"
您的sed
示例不起作用,因为 sed 是一个面向行的工具;它对s///
每一行单独处理命令,而不是对整个文件处理一次。为了使其正常工作,GNU sed 可以选择-z
使用 NUL 作为“行分隔符”(从技术上讲,它仍然基于行,但\n
不再是特殊的)。此外,您的正则表达式没有考虑到多个空格字符。
sed -z -E 's/"\s+"//'
实现相同目的的另一种方法是先使用不同的工具删除换行符:
tr -d '\n' | sed -E 's/"[[:space:]]+"//g'
DNS 区域文件解析器可用于将记录重新格式化为单行:
ldns-read-zone opendkim.txt | sed ...
#!/usr/bin/python
import dns.zonefile
with open("opendkim.txt", "r") as fh:
rrsets = dns.zonefile.read_rrsets(fh.read(),
rdclass=None,
default_ttl=0)
for rrset in rrsets:
print(rrset.name)
for rr in rrset:
string = b"".join(rr.strings)
print(string.decode())