sed使用带反向否定前瞻的嵌套分组正则时报错如何解决?
错误根因
GNU sed 的扩展正则表达式(ERE)引擎原生不支持 Perl 兼容正则(PCRE)中的负向预查语法 (?!pattern),你在正则测试工具中使用的是 PCRE 匹配模式,放到 sed 中就会触发非法正则报错。
解决方案
方案1:使用sed原生逻辑实现(兼容性最高,推荐)
sed 本身支持行匹配过滤,可以先跳过包含bar的镜像行,对剩余行执行替换即可,命令如下:
echo ' image: mydomain/subdomain/foo:old_tag image: mydomain/subdomain/bar:dont_update_me_tag image: mydomain/subdomain/baz:old_tag ' | sed -E '/image:.*bar/! s/(image:.*:).*/\1new_tag/'
逻辑说明:
/image:.*bar/!表示仅对不匹配image:.*bar规则的行,执行后续替换操作s/(image:.*:).*/\1new_tag/为原替换逻辑,将最后一个冒号后的标签内容替换为new_tag
执行后输出完全符合预期:
image: mydomain/subdomain/foo:new_tag image: mydomain/subdomain/bar:dont_update_me_tag image: mydomain/subdomain/baz:new_tag
方案2:使用支持PCRE的工具
如果习惯使用预查语法,可以换用Perl,或者部分发行版的sed提供-P参数启用PCRE支持:
# 使用Perl实现 echo ' image: mydomain/subdomain/foo:old_tag image: mydomain/subdomain/bar:dont_update_me_tag image: mydomain/subdomain/baz:old_tag ' | perl -pe 's/(image:(?!.*bar).*:).*/\1new_tag/' # 支持-P参数的sed可直接用原正则 echo ' image: mydomain/subdomain/foo:old_tag image: mydomain/subdomain/bar:dont_update_me_tag image: mydomain/subdomain/baz:old_tag ' | sed -P 's/(image:(?!.*bar).*:).*/\1new_tag/'
内容的提问来源于stack exchange,提问作者subtleseeker
相关产品推荐
相关产品推荐

