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

Replacing a word over many files using Vim's regex does not work as expected in sed

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

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

因此,例如,在 Vim 中使用它会替代,例如 (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 之外获得我想要的效果。 (第二个问题是:为什么这些行为首先不同?)

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

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

实现等同于Vim的:%s/\<Cat\>/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'