到目前为止,我一直使用EasyGrep来替换多个文件中的文本。不幸的是,当项目变得更大时,它相当慢。似乎非常快的一件事是fugitive.vim的Ggrep,它只搜索我的版本控制文件。所有结果也存储在quickfix列表中。
如何使用Ggrep的结果对所有找到的文件进行简单替换?是否可以在quickfix列表中的所有文件上使用%s/foo/bar/cg
,或者有更好的方法吗?
更新:
现在Vim有了cdo
,请参见Sid的答案。
原始答案:
Vim有bufdo
, windo
, tabdo
和argdo
,这让您可以在所有打开的缓冲区、窗口或文件中执行相同的命令。我们真正需要的是像quickfixdo
这样的东西,它会在快速修复列表中的每个文件上调用命令。不幸的是,Vim缺乏这种功能,但这里有一个解决方案,由Al提供了一个自制的解决方案。使用这个,我们可以运行:
:QFDo %s/foo/bar/gc
这将对快速修复列表中的所有文件运行foo/bar替换。
bufdo
、windo
、tabdo
和argdo
命令有一些共同的行为。例如,如果当前文件无法放弃,则所有这些命令都将失败。我不确定上面提到的QFDo
命令是否遵循相同的约定。
我改编了Al的解决方案创建了一个名为Qargs
的命令。运行此命令会使用快速修复列表中列出的所有文件填充参数列表:
command! -nargs=0 -bar Qargs execute 'args ' . QuickfixFilenames()
function! QuickfixFilenames()
" Building a hash ensures we get each buffer only once
let buffer_numbers = {}
for quickfix_item in getqflist()
let buffer_numbers[quickfix_item['bufnr']] = bufname(quickfix_item['bufnr'])
endfor
return join(values(buffer_numbers))
endfunction
:Ggrep findme
:Qargs
:argdo %s/findme/replacement/gc
:argdo update
编辑:(感谢Peter Rincker)
或者您可以将最后3个命令合并到一行中:
:Ggrep findme
:Qargs | argdo %s/findme/replacement/gc | update
cdo
命令已经添加! 在您使用grep之后,您可以使用cdo
将给定的命令执行到快速修复列表中的每个术语:
cdo %s/<search term>/<replace term>/cg
(查看此Git提交和此vim开发人员Google讨论组以获取有关和添加它背后的动机的更多信息。)
cdo
还可以打开更灵活操作的惊人选项。例如 cdo norm capMy new paragraph
,此示例在每个搜索词出现时运行 normal
,将搜索词周围的整个段落更改为“我的新段落”。令人惊叹的强大。 - Noel Evans:cdo %s/<search term>/<replace term>/gc | update
- antisanelstrom的回答很全面,反映了他在vimdom方面的杰出贡献。它还略微超出了这里所需的范围;可以省略快速修复步骤,而选择用shell命令的结果填充args:
:args `git grep -l findme`
:argdo %s/findme/replacement/gc
:argdo update
这应该是你所需要的全部内容。
编辑: 正如Domon指出的,如果尚未设置,必须首先执行:set hidden!
vim \
git grep -l findme`` - Stephen Emslie:argo ...
之前,我必须先执行 :set hidden
,否则 Vim 会因为未保存的更改而出现错误。 - Domon(使用类似于makeprg/errorformat的grepprg和grepformat;如果grepprg =='internal'则与内部grep相同)
:grep fopen *.c
:copen
:cnext
:vimgrep /\<myVimregexp\>/ **/*.c
:copen
:cnext
:lvimgrep /\<myVimregexp\>/ **/*.c
:lopen
:lnext
等等。
:silent bufdo grepadd fstream %
:copen
:cnext
等等。
:silent argdo grepadd fstream %
:copen
:cnext
有一个补丁可以将cdo(Quickfix do)命令添加到vim中,但尚未被合并(截至2015年3月25日):
https://groups.google.com/forum/#!topic/vim_dev/dfyt-G6SMec
你可能需要自己打补丁来修复vim,以获取此补丁:brew install hg # install mercurial, e.g. with homebrew
hg clone https://vim.googlecode.com/hg/ vim
cd vim
# copy/download patch to . folder
patch -b -p1 < cdo.diff
./configure
make && make install
Qargs
命令中使用-nargs=0
和-bar
。 - Peter Rinckerargs
和argdo
的思路非常优雅!我认为将Qargs
和argdo
命令组合成一个命令会更好(更方便):command! -nargs=1 -complete=command -bang Qargdo exe 'args '.QuickfixFilenames() | argdo<bang> <args>
- ib.:Qargs
е‘Ҫд»Өпјҡhttps://github.com/nelstrom/vim-qargsгҖӮ - nelstromhidden
需要打开(可能作为给初学者的提示,在结尾处)。 - AlexMA