使用sed替换多行文本并在未匹配时返回非0状态码
解决sed跨行替换及匹配失败返回指定状态码的问题
修正后的命令
sed -E ' /^<wodle name="docker-listener">$/{ N s/(\s+<disabled>)no(<\/disabled>)/\1yes\2/ t replaced } b :replaced x s/^$/1/ x $ { x /^1$/q 0 q 100 } ' /etc/test.txt
命令说明
匹配目标行并读取下一行:
/^<wodle name="docker-listener">$/{ ... }精准匹配单独一行的<wodle name="docker-listener">节点行N将下一行内容读入模式空间,此时模式空间包含wodle行和后续的disabled行,解决跨行匹配问题
替换目标内容:
s/(\s+<disabled>)no(<\/disabled>)/\1yes\2/用正则分组保留缩进和标签结构,仅替换no为yes,避免硬写重复文本
标记替换状态:
t replaced若替换成功,跳转到:replaced标签,通过保持空间记录“已替换”状态(将保持空间设为1)b若未匹配或未替换,直接跳过当前块,继续处理下一行
最终状态码判断:
- 处理到最后一行时,检查保持空间的状态:
- 若保持空间为
1(存在替换),返回状态码0 - 若保持空间为空(无匹配替换),返回状态码
100
- 若保持空间为
- 处理到最后一行时,检查保持空间的状态:
原命令问题分析
- 第一个命令失败原因:sed默认以单行模式处理文本,无法匹配跨两行的
<wodle>和<disabled>标签组合,因此找不到替换目标。 - 第二个命令状态码问题:
N;!{q100}的逻辑是“当无法读取下一行(即当前是最后一行)时返回100”,这与是否匹配替换无关——只要文件行数大于1,即使没有匹配内容,N命令能正常执行,最终仍返回0;而如果文件只有一行,无论是否匹配都会返回100,完全不符合需求。
内容的提问来源于stack exchange,提问作者antonisnyc
相关产品推荐
相关产品推荐

