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

psy*_*yho 111 vim replace

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

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

:args ./**
Run Code Online (Sandbox Code Playgroud)

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

:argdo %s/Search/Replace/gce
Run Code Online (Sandbox Code Playgroud)

但是,当我这样做时,Vim的内存使用量从几十MB增加到超过2 GB,这对我来说不起作用.

我也安装了EasyGrep插件,但它几乎不会工作 - 要么它找不到所有的事件,要么只是挂起直到我按下CtrlC.到目前为止,我完成此任务的首选方法是ack-grep搜索术语,使用它的quickfix窗口打开包含该术语的任何文件,之前未打开,最后打开:bufdo %s/Search/Replace/gce.

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

Cas*_*bel 96

这里另一个很大的选择就是不使用vim:

sed -i 's/pattern/replacement/' <files>
Run Code Online (Sandbox Code Playgroud)

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

find . -name *.cpp | xargs sed -i 's/pattern/replacement/'
grep -rl 'pattern1' | xargs sed -i 's/pattern2/replacement/'
Run Code Online (Sandbox Code Playgroud)

等等!

  • 在Mac OS X上,唯一对我有用的sed命令是:`find.-type f | LANG = C xargs sed -i''s/SEARCH/REPLACE/g'` (7认同)
  • @EricJohnson:他们是...`sed`正则表达式,这本质上是POSIX.2基本的正则表达式,但不完全(这是在联机帮助页) - 他们让`\ N`匹配换行符,以及其他一些类似的事情.因此它们与`grep`正则表达式几乎相同. (2认同)

Sid*_*Sid 55

由于最近添加的cdo命令,您现在可以使用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
Run Code Online (Sandbox Code Playgroud)

(cdogrep命令填充的quickfix列表中的每个术语执行给定命令.)

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

  • 另外,您可以添加````:cdo update````来保存所有文件中的更改. (11认同)
  • 为了使用“update”,我必须:“cdo %s/&lt;搜索术语&gt;/&lt;替换术语&gt;/g | 更新` (5认同)
  • :cdo %s/search term/replace term/g 只替换第一次出现的情况,但对我的 vim 中第二次出现的情况不起作用 (2认同)

Eri*_*son 34

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

ack -l 'pattern' | xargs perl -pi -E 's/pattern/replacement/g'
Run Code Online (Sandbox Code Playgroud)

说明

ACK

ACK是一个真棒的命令行工具,它是一个组合grep,find以及全Perl的正则表达式(不只是GNU子集).它以纯Perl编写,速度快,具有语法高亮,适用于Windows,对程序员来说比传统的命令行工具更友好.用Ubuntu安装它sudo apt-get install ack-grep.

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/.


tux*_*fly 27

Greplace适合我.

在github 上还有一个病原体就绪版本.

  • 安装它,我看到其他命令,如`:Gsearch`和`:Gbuffersearch`存在,但当我输入`:Greplace`时,我得到`不是编辑命令:Greplace`. (8认同)
  • 6年后没有什么不寻常的事情,但是这个插件与3年前的最新更新(https://github.com/yegappan/greplace)相比已经过时了.我可以查看Sid的内置解决方案:http://stackoverflow.com/a/38004355/2224331(这不是我在另一个帐户,只是巧合:P) (2认同)

Ben*_*oit 22

也许这样做:

:noautocmd vim /Search/ **/*
:set hidden
:cfirst
qa
:%s//Replace/gce
:cnf
q
1000@a
:wa
Run Code Online (Sandbox Code Playgroud)

说明:

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

*编辑* Vim 8路:

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

:noautocmd vim /Search/ **/*
:set hidden
:cfdo %s//Replace/gce
:wa
Run Code Online (Sandbox Code Playgroud)


exb*_*ary 21

:args从shell命令填充

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

例如,如果您安装了ack 2,

:args `ack -l pattern`
Run Code Online (Sandbox Code Playgroud)

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

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

:args `grep -lr pattern .`  
Run Code Online (Sandbox Code Playgroud)


然后你可以:argdo按照OP的描述使用:

:argdo %s/pattern/replacement/gce
Run Code Online (Sandbox Code Playgroud)


:args从quickfix列表中填充

另请查看nelstrom对相关问题的回答,该问题描述了一个简单的用户定义命令,该命令从当前的quickfix列表中填充arglist.这与许多命令和插件的输出在quickfix列表结束的伟大工程(:vimgrep,:Ack3,:Ggrep4).

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

:vimgrep /pattern/ **/*
:Qargs 
:argdo %s/findme/replacement/gc
Run Code Online (Sandbox Code Playgroud)

在哪里:Qargs调用用户定义的命令,该命令从quickfix列表中填充arglist.

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

链接

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


Ole*_*dov 9

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

far.vom

  • 你还应该说你是插件的作者:) (2认同)

Kyl*_*mus 6

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

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

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

s/<search term>/<replace term>/g替换每个术语。/g意味着替换文件中的每个出现。

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

我根据这个答案及其评论将其拼凑在一起,但觉得它应该得到自己的答案,因为它都集中在一个地方。


dyn*_*yng 5

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

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

也许以下演示解释更多

ctrlsf_edit_demo