使用 Vim 的正则表达式替换多个文件的单词在 sed 中无法按预期工作

Posted

技术标签:

【中文标题】使用 Vim 的正则表达式替换多个文件的单词在 sed 中无法按预期工作【英文标题】:Replacing a word over many files using Vim's regex does not work as expected in sed 【发布时间】:2021-04-25 01:49:24 【问题描述】:

我正在尝试使用正则表达式替换包含代码的许多文件的单词。我不太了解正则表达式,但我可以通过以下命令使用 Vim 在一个文件中获得所需的效果:

:%s/\<Cat\>/Dog/g

因此,例如,在 Vim 中使用 this 将替换,例如 (Cat, Cats) Cat,somethingelse, Cat.blah

(Dog, Cats) Dog,somethingelse, Dog.blah

这正是我想要的!

但是,如果我使用 sed 应用相同的正则表达式(我认为最终我需要使用它来替换许多文件),我会得到例如:

$ line="(Cat, Cats) Cat,somethingelse, Cat.blah"
$ echo "$line" | sed -n "s/\<Cat\>/Dog/p"
(Dog, Cats) Cat,somethingelse, Cat.blah

哪个是错误的输出!

所以我的主要问题是:如何在 Vim 之外获得我想要的效果。 (第二个问题是:为什么这些行为首先不同?)

【问题讨论】:

【参考方案1】:

sed 的修饰符错误,无法达到预期的效果。 -n/p 在这种情况下并不完全正确。你应该用过

sed 's/\<Cat\>/Dog/g'

实现相当于 Vim 的:%s/\&lt;Cat\&gt;/Dog/g 命令。

/g 修饰符具有替换所有匹配字段的效果,即用替换字符串替换多次出现的源字符串。 -n/p 标志在 sed 中用于 conditional print 逻辑,即如果找到模式 Cat,则打印该行。

另外请注意,您仍然可以将-n/p/g 一起使用。但一个关键区别是,如果源字符串不存在,则不会将任何内容打印到标准输出。但是没有它就不会发生同样的事情,你只会看到一个未修改的字符串打印出来。

echo "$line" | sed 's/\<foo\>/Dog/g'
(Cat, Cats) Cat,somethingelse, Cat.blah

及以下不产生输出

echo "$line" | sed -n 's/\<foo\>/Dog/gp'

【讨论】:

哦,我明白了。事后看来我很傻。谢谢! 我知道。我不得不等待几分钟才能接受答案

以上是关于使用 Vim 的正则表达式替换多个文件的单词在 sed 中无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

vim怎么正则查询一个词出现的次数

Vim查找替换及正则表达式的使用

vim正则表达式(转)

使用vim在多个文件中搜索和替换

在 Python 中使用正则表达式查找和替换文件中的单词列表

使用正则表达式检查单词中的一个或多个空格