sed 多行递归模式替换

sed 多行递归模式替换

从以下输入:

serial0/0
SSL disabled
eth0/0
SSL enabled
SSL only
eth0/1
SSL disabled
bgroup0
SSL enabled
eth0/2
SSL disabled
eth0/3
SSL disabled
eth0/4
SSL disabled
bgroup1
SSL disabled
bgroup2
SSL disabled
bgroup3
SSL disabled
vlan1
SSL enabled
null
SSL disabled

我试图获取一个冒号分隔的列表,其中如果输入的下一行以“SSL”开头,它将附加到上一行,因此输出将如下所示:

serial0/0:SSL disabled
eth0/0:SSL enabled:SSL only
eth0/1:SSL disabled
bgroup0:SSL enabled
eth0/2:SSL disabled
eth0/3:SSL disabled
eth0/4:SSL disabled
bgroup1:SSL disabled
bgroup2:SSL disabled
bgroup3:SSL disabled
vlan1:SSL enabled
null:SSL disabled

正如您在此理想输出的第二行中所看到的,应考虑多行以“SSL”开头的情况。基于经典sed指南,我想出了以下sed脚本:

sed -r '/^SSL/! {
        :again
        N
        s/(.*)\n(SSL.*)/\1:\2/
        t again
    }'

这对我来说很有意义,但返回以下输出:

serial0/0:SSL disabled
eth0/0
SSL enabled
SSL only
eth0/1:SSL disabled
bgroup0
SSL enabled
eth0/2:SSL disabled
eth0/3
SSL disabled
eth0/4:SSL disabled
bgroup1
SSL disabled
bgroup2:SSL disabled
bgroup3
SSL disabled
vlan1:SSL enabled
null
SSL disabled

知道我可能做错了什么吗?

答案1

一个更简单的解决方案:

sed -z 's/\nSSL/:SSL/g'

据说-z使用 NUL 作为行分隔符 - 有效地使整个流显示为一行sed。然后,它可以简单地\nSSL用一个序列替换一个:SSL序列,从而按照您希望的方式有效地组合线条。

答案2

您可以使用任何sed风格来执行此操作,无需将整个文件放入内存中,只需使用经典N;P;D循环和分支即可:

sed ':b;$!N;s/\nSSL/:SSL/;tb;P;D' infile

这会拉入Next 行,尝试s替换 - 如果成功,它会分支回:belse 它P会打印,然后Deletes 直到换行符,重新启动循环。

相关内容