Sed seems to replace only the last occurrence in global string substitution

风格不统一 提交于 2019-12-08 00:01:41

问题


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'

This is the expected output:

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

but this is what I get:

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

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


回答1:


Try the following:

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

which yields:

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

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 +.


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:

\*\(.*\)+ 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



来源:https://stackoverflow.com/questions/42400995/sed-seems-to-replace-only-the-last-occurrence-in-global-string-substitution

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!