我发现了Vim的替代命令......
:%s/replaceme/replacement/gi
和vimgrep ......
:vimgrep /findme/gj project/**/*.rb
有没有办法将它们组合起来,以便在目录下的所有文件中进行替换?
答案 0 :(得分:62)
即使我是Vim用户,我通常会使用find
和sed
来做这类事情。 sed
的正则表达式语法类似于Vim(它们都是ed
的后代),但不完全相同。使用GNU sed,您还可以使用-i
进行就地编辑(通常sed
将修改后的版本发送到stdout)。
例如:
find project -name '*.rb' -type f -exec sed -i -e 's/regex/replacement/g' -- {} +
一块一块:
project
=在“项目”树中搜索-name '*.rb'
=表示名称与'* .rb'-type f
=并且是常规文件(不是目录,管道,符号链接等)-exec sed
=使用以下参数运行sed
:
-i
=使用就地编辑-e 's/regex/replacement/g'
=执行“替换”命令(与Vim的:s
几乎相同,但请注意缺少%
- 这是sed
中的默认值< / LI>
--
=标志结束,文件名从此处开始{}
=这告诉find
它找到的文件名应放在sed的命令行上+
=这告诉find
-exec
操作已完成,我们希望将参数分组为尽可能少的sed
次调用(通常比每个文件名运行一次)。要按文件名运行一次,您可以使用\;
代替+
。这是GNU sed
和find
的一般解决方案。在特殊情况下,这可以缩短一点。例如,如果您知道您的名称模式与任何目录都不匹配,则可以省略-type f
。如果您知道所有文件都不以-
开头,则可以省略--
。 Here's an answer I posted to another question with more details on passing filenames found with find
to other commands.
答案 1 :(得分:54)
答案 2 :(得分:7)
您可以运行vimgrep然后记录一个宏,该宏转到vimgrep输出中的每一行并执行替换,如下所示:(不要输入#comments!)
:set autowrite #automatically save the file when we change buffers
:vimgrep /pattern/ ./**/files
qa #start recording macro in register a
:s/pattern/replace/g #replace on the current line
:cnext #go to next matching line
q #stop recording
10000@a #repeat the macro 10000 times, or until stopped by
#an "error" such as reaching the end of the list
:set noautowrite
我还没有测试过,所以可能需要稍微调整一下 - 测试一些你不介意先搞砸的文件。
这个优于sed的优势在于Vim正则表达式更强大,您可以将c选项添加到:s以验证每次替换。
修改强>: 我修改了原来的帖子,因为它错了。我正在使用:1vimgrep来查找每个文件中的第一个匹配项,但我误读了文档 - 它只找到所有文件中的一个匹配项。
答案 3 :(得分:5)
一种方法是打开要在其上运行替换的所有文件(或任何命令),然后运行:bufdo <cmd>
,它将在所有打开的缓冲区上运行<cmd>
。
答案 4 :(得分:4)
有一个插件努力做到这一点:Vimgrep Replace。
哦,等等......还有其他人:Global Replace,EasyGrep。
对于无插件解决方案,如果你可以将argdo
输出到参数列表(可以使用vimgrep
设置),args
可能有帮助,但我可以'似乎弄清楚了细节。如果有人接受了这个想法并对其进行了改进,我会感到高兴......所以就是这样。
第一个插件背后的基本思想(我猜其他插件......)首先使用vimgrep
,然后使用:cnext
循环匹配并在每个插件上应用替换命令线。实现这一目标的功能可以小到足以将其放入.vimrc中。 (也许你可以从插件的来源中解除一个?)
(我想hgimenez可能会找到一个解决方案,但它是否合适可能取决于要处理的文件数量......无论如何插件都应该没问题。)
答案 5 :(得分:2)
回答结合vimgrep和替代品的原始问题:
:vimgrep /pattern/ ./**/files # results go to quickfix list
:set autowrite # auto-save when changing buffers
:silent! cdo %s/replaceme/replacement/gic # cdo draws filenames from quickfix list
:set noautowrite
如果您不想确认每次替换,请忽略c
中的gic
(在这种情况下,您也可以按照@的建议使用find
和sed
LaurenceGonsalves)。
答案 6 :(得分:0)
这适用于少量文件。
vim`找到。 -type f`
:bufdo%s / pattern / replacement / gec |更新