使用vim重构目录中的类/方法/字符串的有效方法

使用vim重构目录中的类/方法/字符串的有效方法,vim,refactoring,Vim,Refactoring,到目前为止,我一直在使用find和replace操作手动重构代码 %s:/stringiwanttoreplace/newstring/g 在维姆 但是,如果我想将StringIwant放在特定目录中的许多文件中,那么这是一个缓慢而费力的过程 我目前/典型的缓慢而费力的过程涉及grep:- grep -rn "stringiwanttoreplace" . 在my terminal中显示StringIwantReplace所在的所有位置/文件名;现在我知道哪些文件包含StringIwant

到目前为止,我一直在使用find和replace操作手动重构代码

%s:/stringiwanttoreplace/newstring/g 
在维姆

但是,如果我想将StringIwant放在特定目录中的许多文件中,那么这是一个缓慢而费力的过程

我目前/典型的缓慢而费力的过程涉及grep:-

grep -rn "stringiwanttoreplace" .
在my terminal中显示StringIwantReplace所在的所有位置/文件名;现在我知道哪些文件包含StringIwantReplace,我将逐个打开每个文件,在每个文件中执行查找和替换操作

是否有更高效的工作流程(在vim中)来完成此任务


澄清:我更喜欢基于vim的解决方案,而不是bash脚本/一行程序。

您不需要
vim
来实现这一点,您可以使用命令行工具。在文件列表的循环中使用
sed
,可以自动执行此操作。大概是这样的:

for each in `grep -l "stringiwanttoreplace" *` ;
do
    cat $each | sed -e "s/stringiwanttoreplace/newstring/g" > $each
; done
您可以从Vim中调用它(
:!find…
),但不需要:

find . -type f | xargs sed -i 's/stringiwanttoreplace/newstring/g'
使用中描述的几十个参数微调文件选择

man find
(例如,仅在HTML文件中替换:
-name\*.HTML

此解决方案将尝试替换所有文件。你以前可以通过grep过滤,但那只是做了两倍的工作而没有任何收获


顺便说一下:
sed
对正则表达式使用的语法与Vim几乎相同(源于相同的历史)。

如果您真的想在Vim中使用它,您可以按照建议操作。

您可以打开所有文件并键入

:bufdo :s/stringiwanttoreplace/newstring/g

它在所有缓冲区中执行搜索/替换。

vim7内置了递归grep

:vimgrep /pattern/[j][g] file file1 file2 ... fileN
结果将显示在快速修复窗口中(:help quickfix)

要递归执行搜索,请使用
**
-通配符,如


***.c
搜索当前文件夹并递归搜索所有子目录。

以下是我将使用的完整命令序列:

/stringiwanttoreplace
:vimgrep /<c-r>// **
:Qargs
:argdo %s//newstring/g
:argdo update
将其添加到
vimrc
文件中

运行了
:Qargs
,我们的参数列表现在应该包含包含目标字符串的所有文件。因此,我们可以使用
:argdo
运行替换命令,以在每个文件中执行该命令。我们可以将替换命令的搜索字段留空,它将自动使用最新的搜索模式。如果需要,可以在运行替换命令时包含
c
标志,然后系统会提示您进行确认

最后,使用
:argdo update
命令保存更改的每个文件

如前所述,您应该确保Vim的选项已启用,否则在将任何更改写入活动缓冲区之前,当您尝试切换到另一个缓冲区时,它将引发错误

另外,请注意,最后3个命令可以在单个命令行中执行,方法是使用管道字符分隔它们

:Qargs | argdo %s//replacement/gc | update

:Qargs
命令是(由我)从中掐出来的,而我的灵感又来自于。作者发布了一篇非常好的文章,这向我建议Vim应该真正实现像
:quickfixdo
这样的本地功能。

我希望使用基于Vim的解决方案,而不是bash脚本。这很公平,但这更简单-您不需要调用Vim并循环浏览文件。这是一个一步操作。如果我在vim缓冲区内执行此操作,我可以使用一个标准输出来准确显示哪些文件已被修改吗?我主要在一个干净的Git工作树中使用它,然后是一个
Git status
Git diff
。如果这对您不起作用,您可以使用,例如,
sed-i.SOMESTRANGESTRING…
。然后,
sed
将创建备份,您也可以使用
find-name\*。some奇怪的字符串
。谢谢,
:argdo
对我来说是新的。哦,是的。我总是忘记
:args
+1我同意
:argdo
是一种方法,但运行
:args app/views/*/*
是一种分散的填充参数列表的方法。该列表可能包含不包含要替换的搜索匹配项的文件,因此在运行替换命令时需要包含
e
标志。使用
:vimgrep
填充快速修复列表,然后将该列表中引用的每个文件复制到参数列表中。这保证了
:argdo%s//replacement/g
仅在包含目标字符串的文件上运行。@nelstorm:您可能希望提到使用
设置隐藏
或执行
:argdo%s//newstring/g | update
,因为默认情况下
:argdo
不会放弃文件。我更喜欢加入
Qargs
argdo
命令合一:
命令-nargs=1-complete=command-bang Qargdo exe'args'。QuickfixFilenames()| argdo
。谢谢@nelstrom。尝试过这个,效果很好!:-)现在我有了一个新的vim技巧,多亏了你。非常感谢您的超级详细的答案!我创建了一个简单的插件来包装
:Qargs
命令:
:Qargs | argdo %s//replacement/gc | update