Solaris系统下sed正则删除特定dn块的实现疑问
用sed实现删除以dn: abcd开头的文本块的解决方案
你遇到的问题很典型——很多在PCRE兼容工具(比如regex101)里好用的正则,放到sed里就失效了,核心原因是sed默认是逐行处理,而且不支持PCRE里的单行模式((?s))、负向前瞻((?!...))这类语法。不过别担心,我们完全可以用sed自身的特性来实现你的需求,下面给你两种可行的方案:
方案1:用GNU sed的-z选项(简单直观)
GNU sed提供了-z选项,它会把整个文件读成一个连续的数据流(用null字符分隔内容,相当于保留所有换行符,把整个文件当成一个大字符串处理),这样就能用类似PCRE的多行匹配逻辑了。
执行下面的命令即可:
sed -z 's/(^|\n\n)dn: abcd[^\n]*\n\n/\1/g' 你的文件名.txt
命令解释:
-z:让sed不再逐行处理,而是把整个文件加载到缓冲区(^|\n\n):匹配块的起始边界——要么是文件开头,要么是两个换行符(也就是前一个块的结束标记)dn: abcd[^\n]*:匹配从dn: abcd开始到该行末尾的所有内容\n\n:匹配块的结束标记\1:把匹配到的起始边界(空或者\n\n)替换回去,避免破坏剩余块之间的分隔结构
方案2:传统sed多行处理(兼容更多环境)
如果你的环境里没有GNU sed(比如macOS默认的BSD sed),可以用sed的多行累积命令来实现,不需要依赖扩展选项:
sed '/^dn: abcd/{:a;N;/\n\n$/!ba;d}' 你的文件名.txt
命令解释:
/^dn: abcd/:找到以dn: abcd开头的行,触发后续操作:a:定义一个循环标签aN:把下一行追加到当前缓冲区里/\n\n$/!ba:如果缓冲区的结尾不是\n\n(还没到块的结束),就跳回标签a继续追加行d:当缓冲区里的内容包含完整的块(到\n\n结束),就删除整个缓冲区的内容
这两种方案都能精准删除所有以dn: abcd开头、以\n\n结尾的文本块,你可以根据自己的环境选择合适的方式。
内容的提问来源于stack exchange,提问作者Adami
相关产品推荐
相关产品推荐

