如何用Sed删除包含指定文本的###与@@@区间所有行?支持多匹配
解决方案
用 sed 实现单匹配(删除包含"A"的区间)
你之前用的sed "/###/,/@@@/d"会删除所有区间,因为它只要匹配到首尾就删,没做内容判断。要实现条件删除,得用状态标记+循环读取整个区间:
sed -n ' /###/{ :loop N /@@@/!b loop /A/!p }' your_file.txt
逻辑说明:
-n让sed只打印我们指定的内容- 碰到
###就开始循环读取后续行,直到读到@@@,把整个区间内容存在模式空间 - 只有当区间里**不包含"A"**时,才打印这个区间
支持多匹配(删除包含"A"或"D"的区间)
要匹配多个关键词,修改判断条件即可:
sed -E -n ' /###/{ :loop N /@@@/!b loop /(A|D)/!p }' your_file.txt
这里用-E开启扩展正则,用(A|D)表示匹配A或D;如果是不支持扩展正则的sed版本,把条件改成/A\|D/就行。
用 awk 实现(逻辑更直观)
awk处理这类区间+内容判断的场景更灵活,代码可读性更高:
单匹配(删除含"A"的区间)
awk ' /###/{flag=1; buf=""} flag{buf=buf $0 "\n"} /@@@/{ flag=0 if(buf !~ /A/) print buf }' your_file.txt
多匹配(删除含"A"或"D"的区间)
awk ' /###/{flag=1; buf=""} flag{buf=buf $0 "\n"} /@@@/{ flag=0 if(buf !~ /A|D/) print buf }' your_file.txt
逻辑说明:
- 遇到
###时,开启标记flag并清空缓冲区buf - 标记开启时,把每行内容追加到缓冲区
- 遇到
@@@时关闭标记,检查缓冲区是否不包含目标关键词,是则打印整个区间
内容的提问来源于stack exchange,提问作者huz_akh
相关产品推荐
相关产品推荐

