sed 似乎只替换了全局字符串替换中的最后一次出现 [英] Sed seems to replace only the last occurrence in global string substitution

查看:58
本文介绍了sed 似乎只替换了全局字符串替换中的最后一次出现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用了这个命令,但它不是广告预期的工作:

I use this command, but it's not working ad intended:

echo "0+223+141+800+450+1*(106+400)+1*(1822+500)+1*(183+400)" | sed 's/\*\(.*\)+/*\1suma/g'

这是预期的输出:

0+223+141+800+450+1*(106suma400)+1*(1822suma500)+1*(183suma400)

但这就是我得到的:

0+223+141+800+450+1*(106+400)+1*(1822+500)+1*(183suma400)

尽管使用了 g,但看起来只有最后一次被替换.

It looks like only the last occurrence is being replaced, despite the use of g.

推荐答案

尝试以下操作:

echo "0+223+141+800+450+1*(106+400)+1*(1822+500)+1*(183+400)" |
    sed 's/\(\*([^+]*\)+/\1suma/g'

产生:

0+223+141+800+450+1*(106suma400)+1*(1822suma500)+1*(183suma400)

诀窍是避免 sed 总是 greedy 匹配,因此使用表达式 [^+]* 而不是 .*,以便只匹配next +.

The trick is to avoid sed's invariably greedy matching, so expression [^+]* is used instead of .*, so as to only match up to the next +.

请注意,您的尝试不仅替换了最后次出现的预期模式,而且 - 由于贪婪匹配 - 仅发现 1 个匹配跨越 多个 预期的模式,它取代了:

Note that your attempt didn't only replace the last occurrence of your intended pattern, but - due to greedy matching - found only 1 match spanning multiple intended patterns, which it replaced:

\*\(.*\)+ 匹配 *(106+400)+1*(1822+500)+1*(183+ - 从第一个 * 文字到 last + 文字,捕获组 \1 因此扩展为 (106+400)+1*(1822+500)+1*(183

\*\(.*\)+ matched *(106+400)+1*(1822+500)+1*(183+ - everything from the first * literal to the last + literal, and capture group \1 therefore expanded to (106+400)+1*(1822+500)+1*(183

这篇关于sed 似乎只替换了全局字符串替换中的最后一次出现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆