我正在寻找在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)
等等!
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)
(cdo对grep命令填充的quickfix列表中的每个术语执行给定命令.)
(c如果要在不确认的情况下替换每个搜索词,请删除第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是一个真棒的命令行工具,它是一个组合grep,find以及全Perl的正则表达式(不只是GNU子集).它以纯Perl编写,速度快,具有语法高亮,适用于Windows,对程序员来说比传统的命令行工具更友好.用Ubuntu安装它sudo apt-get install ack-grep.
Xargs是一个旧的unix命令行工具.它从标准输入读取项目并执行指定的命令,然后执行标准输入读取的项目.所以基本上ack生成的文件列表被附加到perl -pi -E 's/pattern/replacemnt/g'命令的末尾.
Perl是一种编程语言.-p选项使Perl在程序周围创建一个循环,该循环遍历文件名参数.-i选项使Perl在适当的位置编辑文件.您可以修改它以创建备份.-E选项使Perl执行指定为程序的一行代码.在我们的例子中,该程序只是一个Perl正则表达式替换.有关Perl命令行选项的更多信息perldoc perlrun.有关Perl的更多信息,请访问http://www.perl.org/.
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. :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 每次替换后保存文件。
我根据这个答案及其评论将其拼凑在一起,但觉得它应该得到自己的答案,因为它都集中在一个地方。
如果你不介意引入外部依赖,我已经酿造了一个插件ctrlsf.vim(取决于ack或ag)来完成这项工作.
它可以格式化并显示来自ack/ag的搜索结果,并将结果缓冲区中的更改与磁盘上的实际文件同步.
也许以下演示解释更多
