如何编写sed脚本为含指定模式的单词添加前缀?
嘿,我来帮你搞定这个sed脚本的问题!看起来你已经懂点捕获组,但卡在了如何精准匹配单个单词,还有\s不生效的坑上,咱们一步步解决:
1. 先解决\s不生效的问题
sed默认用的是基本正则表达式(BRE),这个模式下\s不是合法的元字符,会被当成普通的\和s字符来处理。你有两个替代方案:
- 在BRE里用
[[:space:]]匹配任意空白符(空格、制表符都算),用[^[:space:]]匹配非空白字符; - 切换到扩展正则表达式(ERE),给sed加
-E参数(GNU sed)或者-r参数(BSD sed),这时\s(空白符)、\S(非空白符)、\b(单词边界)这些更简洁的写法就都能正常用了。
2. 精准捕获单个单词并添加前缀
你的核心需求是给包含特定模式的完整单词加前缀,关键是要界定单词的边界,避免像你之前那样用.*贪婪匹配整行内容。
针对你的例子(给包含foo的单词加qux前缀),这里有两种靠谱的写法:
写法一:用BRE(无需额外参数)
sed 's/\(\<[^[:space:]]*foo[^[:space:]]*\>\)/qux\1/g'
\<:匹配单词的起始边界[^[:space:]]*:匹配零个或多个非空白字符(构成单词的主体)foo:你要找的特定模式\>:匹配单词的结束边界\1:引用捕获到的完整单词,替换成qux\1就完成了前缀添加g:全局替换,确保一行里所有符合条件的单词都被处理
写法二:用ERE(更简洁)
sed -E 's/(\b\S*foo\S*\b)/qux\1/g'
\b:单词边界(比\</\>更直观)\S*:匹配零个或多个非空白字符(和[^[:space:]]*效果一样)- 其他部分和BRE写法逻辑一致
用这两个命令处理你的输入:
foobarbaz barfoobaz barbazfoo barbaz
都会得到你想要的结果:
quxfoobarbaz quxbarfoobaz quxbarbazfoo barbaz
3. 为啥你之前的写法不对
你尝试的s/\(.*\)men\(.*\)/...里,.*是贪婪匹配,会把men前面的所有内容都塞进\1,后面的所有内容塞进\2,这是针对整行的替换,根本没聚焦到单个单词。要处理单个单词,必须用边界符+非空白字符的组合,把匹配范围限制在单个单词内才行。
内容的提问来源于stack exchange,提问作者Ace shinigami
相关产品推荐
相关产品推荐

