Mac zsh环境下sed命令替换foo/bar失效问题排查
Mac OS zsh环境下sed替换foo/bar失效的原因及解决方法
问题场景
执行以下命令时,foo并未被替换为连字符:
echo "foo,baz" | sed 's/\(foo\|bar\)/-/g' # 输出:foo,baz
目前通过两次sed管道实现了需求,但想知道原命令的问题所在:
echo "foo,baz" | sed 's/\(foo\)/-/g' | sed 's/\(bar\)/-/g' # 输出:-,baz
问题根源
Mac OS自带的sed是BSD版本,默认使用**基本正则表达式(BRE)**语法。在BRE规则里,|(或逻辑)不被支持——哪怕给它加了转义也没用。你写的\(foo\|bar\)是GNU sed(Linux系统默认版本)里的BRE兼容写法,但BSD sed不支持该语法,导致正则匹配失败,自然不会执行替换。
正确解决方法
有两种简单的修正方式:
- 启用扩展正则表达式(ERE):添加
-E参数,无需给括号和|转义,直接写逻辑或即可:
echo "foo,baz" | sed -E 's/(foo|bar)/-/g' # 输出:-,baz
- 单条sed内执行多次替换:在BSD BRE规则下,可分号分隔多个替换指令,效果与你的管道方式一致,但只启动一次sed进程:
echo "foo,baz" | sed 's/foo/-/g; s/bar/-/g'
补充说明
你当前用两次sed管道的方式是可行的,但相比单条sed命令,多启动了一个进程,效率略低。上述第一种方法是最简洁高效的实现方式。
内容的提问来源于stack exchange,提问作者javanoob
相关产品推荐
相关产品推荐

