使用 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/\<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'
【讨论】:
哦,我明白了。事后看来我很傻。谢谢! 我知道。我不得不等待几分钟才能接受答案以上是关于使用 Vim 的正则表达式替换多个文件的单词在 sed 中无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章