我在 Vim 中使用 Ack 插件,它可以帮助我在项目中快速搜索字符串。但是,有时我想替换所有或部分找到的字符串。您可以使用 Vim arglist 进行某种全局搜索和替换,如下所示(来源):
:args app/views/*/*
:argdo %s/, :expire.*)/)/ge | update
但不是使用args
,我更愿意通过 Ack 进行搜索,然后在所有找到的文件中进行替换。有没有类似于argdo
命令的方法?
我决定在 Vim 之外使用ack
并perl
解决这个问题,这样我就可以使用更强大的 Perl 正则表达式而不是 GNU 子集。您可以将其映射到.vimrc
.
ack -l 'pattern' | xargs perl -pi -E 's/pattern/replacement/g'
ack
ack是一个很棒的命令行工具,它混合了grep
、find
和完整的 Perl 正则表达式(不仅仅是 GNU 子集)。它是用纯 Perl 编写的,速度快,具有匹配突出显示功能,可以在 Windows 上运行,并且比传统的命令行工具对程序员更友好。在 Ubuntu 上安装它sudo apt-get install ack-grep
。
xargs
xargs是一个旧的 Unix 命令行工具。它从标准输入读取项目并执行指定的命令,然后执行为标准输入读取的项目。所以基本上生成的文件列表ack
被附加到perl -pi -E 's/pattern/replacement/g'
命令的末尾。
perl -pi -E
Perl 是一种编程语言。
该-p
选项使 Perl 围绕您的程序创建一个循环,该循环遍历文件名参数。
该-i
选项使 Perl 就地编辑文件。您可以修改它以创建备份。
该-E
选项使 Perl 执行指定为程序的一行代码。在我们的例子中,程序只是一个 Perl 正则表达式替换。
有关 Perl 命令行选项的更多信息,请参阅perldoc perlrun
. 有关 Perl 的更多信息,请参见http://www.perl.org/。
现在,Vim 有了这个新命令cdo
,它将对快速修复列表的每一行运行给定的命令。
所以你可以使用
:Ack pattern
:cdo s/pattern/newpattern/g
我不相信有一种内置的方法可以做到这一点,但它应该很容易制作。
您需要做的是创建一个调用自定义函数的命令。然后该函数应该使用该getqflist()
函数来获取 quickfix 列表中的所有条目并exe
执行脏活。小心你作为参数传递的内容!
" Define a command to make it easier to use
command! -nargs=+ QFDo call QFDo(<q-args>)
" Function that does the work
function! QFDo(command)
" Create a dictionary so that we can
" get the list of buffers rather than the
" list of lines in buffers (easy way
" to get unique entries)
let buffer_numbers = {}
" For each entry, use the buffer number as
" a dictionary key (won't get repeats)
for fixlist_entry in getqflist()
let buffer_numbers[fixlist_entry['bufnr']] = 1
endfor
" Make it into a list as it seems cleaner
let buffer_number_list = keys(buffer_numbers)
" For each buffer
for num in buffer_number_list
" Select the buffer
exe 'buffer' num
" Run the command that's passed as an argument
exe a:command
" Save if necessary
update
endfor
endfunction
你可以通过这种方式使用 ack
:args `ack -l User app/`
:argdo %s/, :expire.*)/)/ge | update
或使用 ag
:args `ag -l User app/`
:argdo %s/, :expire.*)/)/gec | w
我使用 MacVim(mvim
在 shell 中激活)。我将结果ack
传递给mvim
:
mvim -f $(ack -l $@)
然后在 MacVim 中,我搜索/替换使用bufdo
:
:bufdo %s/SEARCH/REPLACE/gce | update
c
如果不需要确认,则省略该选项。