为什么sed-substitute命令中的结束g关键字与所有出现的情况不匹配?

为什么sed-substitute命令中的结束g关键字与所有出现的情况不匹配?,sed,Sed,我想在多个上下文中用另一个字符串替换一个字符串 我编写了一个匹配每个上下文的regexp,然后编写了替换,然后添加了g关键字,以确保同一行的所有匹配项都被替换 这是我试图翻译的文件(test.txt)的一个示例: "keyword" "tremor" 000,tremor tremor word word tremor word word tremor word tremor word tremor // tremor //tremor tremor qer_editorImage tr

我想在多个上下文中用另一个字符串替换一个字符串

我编写了一个匹配每个上下文的regexp,然后编写了替换,然后添加了
g
关键字,以确保同一行的所有匹配项都被替换

这是我试图翻译的文件(
test.txt
)的一个示例:

"keyword" "tremor"
000,tremor
tremor
word word tremor word
word tremor word tremor word tremor
// tremor
//tremor
tremor
    qer_editorImage tremor
    diffuseMap  tremor
    aniMap tremor tremor tremor tremor
这是我编写的sed(
test.sed
)文件:

s#\(^\|//\|[," \t]\)tremor\([" \t]\|$\)#\1niveus\2#gI
这是我运行sed的方式:

sed -f test.sed test.txt
这就是我对
aniMap
行的期望:

    aniMap niveus niveus niveus niveus
这是我得到的:

    aniMap niveus tremor niveus tremor

编辑:我想这与下一个事件是被替换的前一个事件的一部分有关,如果是,如何解决这个问题?

正如您所注意到的,正则表达式的结尾与下一个事件的开始相匹配

如果我们用方括号分隔第一个匹配:

    aniMap[ tremor ]tremor tremor tremor
应该清楚的是,第二次出现的“颤振”与regexp不匹配。通常不可能创建没有此问题的regexp

一个简单的解决方法是不使用/g,而是循环命令直到失败:

:x
s#\(^\|//\|[," \t]\)tremor\([" \t]\|$\)#\1niveus\2#I
tx

(保留/g更有效,但如果不使用它,替换将从左到右进行)

只需使用
\b
作为单词边界

sed-E's/\bniveus\b/tremor/g'

您不必担心替换中的
\b
。。。它是一个零长度匹配,如模式空间的开始部分为
^
,结束部分为
$


如果您担心子字符串,它不会将
niveusxxx
替换为
tremorxxx
,我认为这是您的发展方向。

很高兴知道!我想我可以在
:x
tx
之间放上我想要的任何一行?只需要两个循环来匹配
aniMap[tremor]tremor[tremor]tremor
然后
aniMap-niveus[tremor]niveus[tremor]
,所以循环可能是可以接受的。另外注意,因为我无法编辑我之前的注释:在同时使用循环和
/g
时,它只运行两次,所以,这也很有效!虽然@stevesliva的解决方案更符合我的实际需要,但感谢您教会了我一些东西,我相信下次我会重复使用。这就是我一直在寻找的答案,我问这个问题也是因为我想了解发生了什么,而不仅仅是因为我需要一个解决方案。:-)@ThomasDebesse Upvoting几乎和获得一个被接受的答案一样有价值,所以如果你能做到的话,请回过头来。悬停文字是“这个答案很有用”,所以它是合适的。是的,但我还没有足够的声誉来投票:-)所以,虽然没有回答问题本身(@jhnc做了什么),但它完全满足了我的需要!很遗憾,我不能将这两个答案选为“选定”答案。:-)