58

我在 Vim 中使用 Ack 插件,它可以帮助我在项目中快速搜索字符串。但是,有时我想替换所有或部分找到的字符串。您可以使用 Vim arglist 进行某种全局搜索和替换,如下所示(来源):

:args app/views/*/*
:argdo %s/, :expire.*)/)/ge | update

但不是使用args,我更愿意通过 Ack 进行搜索,然后在所有找到的文件中进行替换。有没有类似于argdo命令的方法?

4

5 回答 5

98

我决定在 Vim 之外使用ackperl解决这个问题,这样我就可以使用更强大的 Perl 正则表达式而不是 GNU 子集。您可以将其映射到.vimrc.

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

解释

ack

ack是一个很棒的命令行工具,它混合了grepfind和完整的 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/

于 2012-01-05T14:28:22.913 回答
50

现在,Vim 有了这个新命令cdo,它将对快速修复列表的每一行运行给定的命令。

所以你可以使用

:Ack pattern
:cdo s/pattern/newpattern/g
于 2016-08-24T09:15:55.073 回答
16

我不相信有一种内置的方法可以做到这一点,但它应该很容易制作。

您需要做的是创建一个调用自定义函数的命令。然后该函数应该使用该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
于 2011-01-25T12:12:27.557 回答
10

你可以通过这种方式使用 ack

:args `ack -l User app/`
:argdo %s/, :expire.*)/)/ge | update

或使用 ag

:args `ag -l User app/`
:argdo %s/, :expire.*)/)/gec | w
于 2013-03-31T12:56:31.823 回答
9

我使用 MacVim(mvim在 shell 中激活)。我将结果ack传递给mvim

mvim -f $(ack -l $@)

然后在 MacVim 中,我搜索/替换使用bufdo

:bufdo %s/SEARCH/REPLACE/gce | update

c如果不需要确认,则省略该选项。

于 2012-04-25T19:24:22.650 回答