在Vim中搜索并替换所有项目文件

时间:2011-01-26 12:10:25

标签: vim replace

我正在寻找在Vim中对所有项目文件进行搜索和替换(确认)的最佳方法。 “项目文件”是指当前目录中的文件,其中一些文件不必打开。

执行此操作的一种方法是简单地打开当前目录中的所有文件:

:args ./**

然后对所有打开的文件进行搜索和替换:

:argdo %s/Search/Replace/gce

然而,当我这样做时,Vim的内存使用量从几十MB增加到超过2 GB,这对我不起作用。

我也安装了EasyGrep插件,但它几乎从不起作用 - 要么找不到所有出现的内容,要么直到按 Ctrl C才会挂起。到目前为止,我完成此任务的首选方法是ack-grep搜索词,使用它的quickfix窗口打开包含该词的任何文件,之前未打开,最后:bufdo %s/Search/Replace/gce

我正在寻找一个可以用于此的好的,有效的插件,或者一个命令/命令序列,它比我现在使用的那个更容易。

11 个答案:

答案 0 :(得分:93)

这里的另一个重要选择就是不使用vim:

sed -i 's/pattern/replacement/' <files>

或者如果您有某种方法可以生成文件列表,可能是这样的:

find . -name *.cpp | xargs sed -i 's/pattern/replacement/'
grep -rl 'pattern1' | xargs sed -i 's/pattern2/replacement/'

等等!

答案 1 :(得分:48)

感谢最近添加的cdo command,您现在可以使用已安装的grep工具在两个简单的命令中执行此操作。无需额外的插件!:

1. :grep <search term>
2. :cdo %s/<search term>/<replace term>/gc
3. (If you want to save the changes in all files) :cdo update

cdo对quickfix列表中的每个术语执行给定命令,grep命令填充该命令。)

(如果要在不确认每次搜索的情况下替换每个搜索词,请删除第二个命令末尾的c

答案 2 :(得分:33)

我决定使用ack和Perl来解决这个问题,以便利用更强大的完整Perl正则表达式而不是GNU子集。

ack -l 'pattern' | xargs perl -pi -E 's/pattern/replacement/g'

解释

ACK

ack是一个很棒的命令行工具,它混合了grepfind和完整的Perl正则表达式(不仅仅是GNU子集)。它以纯Perl编写,速度快,具有语法高亮,适用于Windows,对程序员来说比传统的命令行工具更友好。使用sudo apt-get install ack-grep在Ubuntu上安装它。

xargs的

Xargs是一个旧的unix命令行工具。它从标准输入读取项目并执行指定的命令,然后执行标准输入读取的项目。因此,ack生成的文件列表基本上被附加到perl -pi -E 's/pattern/replacemnt/g'命令的末尾。

perl -pi

Perl是一种编程语言。 -p选项使Perl在程序周围创建一个循环,该循环遍历文件名参数。 -i选项使Perl在适当的位置编辑文件。您可以修改它以创建备份。 -E选项使Perl执行指定为程序的一行代码。在我们的例子中,该程序只是一个Perl正则表达式替换。有关Perl命令行选项perldoc perlrun的更多信息。有关Perl的更多信息,请参阅http://www.perl.org/

答案 3 :(得分:26)

Greplace对我很有用。

github上还有一个pathogen ready version

答案 4 :(得分:22)

也许这样做:

:noautocmd vim /Search/ **/*
:set hidden
:cfirst
qa
:%s//Replace/gce
:cnf
q
1000@a
:wa

说明:

  • :noautocmd vim /Search/ **/*⇒查找(vim是cwd所有子目录中所有文件的vimgrep)模式的缩写,但没有触发autocmds(:noautocmd),为了速度的缘故
  • :set hidden⇒允许修改缓冲区未显示在窗口中(可能在您的vimrc中)
  • :cfirst⇒跳转到第一个搜索结果
  • qa⇒开始将宏记录到寄存器 a
  • :%s//Replace/gce⇒用/Search/替换所有上次搜索模式(当时仍为Replace):
    • 在同一行(g标志)
    • 上多次
    • 用户确认(c标志)
    • 如果找不到模式(e标志),则
    • 没有错误
  • :cnf⇒跳转到vim命令创建的列表中的下一个文件
  • q⇒停止录制宏
  • 1000@a⇒播放1000次存储在寄存器中的宏
  • :wa⇒保存所有已修改的缓冲区

*编辑* Vim 8路:

从Vim 8开始,有一种更好的方法,因为:cfdo迭代了quickfix列表中的所有文件:

:noautocmd vim /Search/ **/*
:set hidden
:cfdo %s//Replace/gce
:wa

答案 5 :(得分:21)

从shell命令

填充:args

可以(在某些操作系统上 1 ))通过shell命令提供:args的文件。

例如,如果您安装了 2

:args `ack -l pattern`

将要求ack返回包含'pattern'的文件列表,并将它们放在参数列表中。

或者用普通的'grep'我猜它会是:

:args `grep -lr pattern .`  


然后,您可以按照OP:

的描述使用:argdo
:argdo %s/pattern/replacement/gce


从快速修复列表中填充:args

另请查看nelstrom's answer相关问题,该问题描述了从当前quickfix列表填充arglist的简单用户定义命令。这适用于许多命令和插件,其输出最终位于quickfix列表中(:vimgrep:Ack 3 :Ggrep 4 )。

然后可以使用以下命令执行项目范围搜索的序列:

:vimgrep /pattern/ **/*
:Qargs 
:argdo %s/findme/replacement/gc

其中:Qargs是对用户定义的命令的调用,该命令从quickfix列表填充arglist。

您还可以在ensuing discussion中找到简单插件中的链接,这些插件可将此工作流程缩减为2或3个命令。

链接

  1. :h {arglist} - vimdoc.sourceforge.net/htmldoc/editing.html#{arglist}
  2. 确认 - betterthangrep.com/
  3. ack.vim - github.com/mileszs/ack.vim
  4. 逃犯 - github.com/tpope/vim-fugitive

答案 6 :(得分:7)

2016年的另一个选项far.vim插件:

far.vom

答案 7 :(得分:5)

如果你不介意引入外部依赖,我已经制作了一个插件ctrlsf.vim(取决于ackag)来完成这项工作。

它可以格式化并显示来自ack / ag的搜索结果,并将结果缓冲区中的更改与磁盘上的实际文件同步。

也许以下演示解释更多

ctrlsf_edit_demo

答案 8 :(得分:0)

基本上,我想在单个命令中更换,更重要的是在vim内部

基于answer by @Jefromi我创建了一个键盘快捷键,我在.vimrc文件中设置了这样的

nmap <leader>r :!grep -r -l  * \| xargs sed -i -e 's///g'

现在从vim,在leader + r的笔划中我得到了在vim中加载的命令,我编辑如下,

:!grep -r -l <find> <file pattern> | xargs sed -i -e 's/<find>/<replace>/g'

因此,我用一个命令替换,更重要的是在vim本身

答案 9 :(得分:0)

1. :grep <search term> (or whatever you use to populate the quickfix window)
2. :cfdo s/<search term>/<replace term>/g | update

步骤1使用所需的项填充快速修复列表。在这种情况下,它与您想通过grep进行更改的搜索词一起传播。

cfdo在quickfix列表中的每个文件上运行以下命令。键入:help cfdo以获得详细信息。

s/<search term>/<replace term>/g替换每个术语。 /g表示替换文件中的所有匹配项。

| update在每次替换后保存文件。

我根据this answer及其评论将它们拼凑在一起,但是由于它全部集中在一个地方,因此觉得它值得自己回答。

答案 10 :(得分:0)

  1. 确保您正在使用Neovim(或Vim 7.4.8+,但实际上只是使用Neovim)
  2. 为命令行和Vim插件安装FZF
  3. 安装Ag,以便FZF在vim中自动可用
  4. 如果在OSX上使用iTerm2,请将alt / option键设置为Esc +

用法

在当前目录中搜索您要更改的文本,并将其作为子项

:Ag text

  • 保持键入以模糊过滤项
  • 选择带有alt-a的项目
  • 取消选择带有alt-d的项目
  • Enter将填充快速修复列表
  • :cfdo%s / text / newText / g | :w

现在您已经在Vim NeoVim内部制作了小玩意

source