Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Search 如何进行搜索&;替换为vim中的ack?_Search_Vim_Replace_Ack - Fatal编程技术网

Search 如何进行搜索&;替换为vim中的ack?

Search 如何进行搜索&;替换为vim中的ack?,search,vim,replace,ack,Search,Vim,Replace,Ack,我在Vim中使用Ack插件,它帮助我在项目中快速搜索字符串。但是,有时我希望替换所有或部分找到的字符串。您可以使用Vim arglist进行某种全局搜索和替换,如下所示() : 但是,与使用args不同,我更愿意通过Ack进行搜索,然后在找到的所有文件中进行替换。有没有类似于argdo命令的方法?我不相信有一种内置的方法可以做到这一点,但它应该很容易实现 您需要做的是创建一个调用自定义函数的命令。然后,该函数应使用getqflist()函数获取quickfix列表中的所有条目,并使用exe执行脏

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


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

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

您需要做的是创建一个调用自定义函数的命令。然后,该函数应使用
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
“定义命令以使其更易于使用
命令!-nargs=+QFDo调用QFDo()
“起作用的功能
功能!QFDo(指挥部)
“创建一本字典,这样我们就可以
“获取缓冲区列表,而不是
“缓冲区中的行列表(简易方式
“获取唯一的条目)
让缓冲区_数={}
“对于每个条目,使用缓冲区编号作为
“字典键(不会重复)
对于getqflist()中的fixlist_条目
让缓冲区编号[固定列表项['bufnr']]=1
外循环
“把它列在一个清单上,因为它看起来更干净
让缓冲区编号列表=键(缓冲区编号)
“对于每个缓冲区
对于缓冲区\u编号\u列表中的num
“选择缓冲区
exe'buffer'num
“运行作为参数传递的命令
exe a:命令
“必要时保存
更新
外循环
端功能

我决定使用
ack
perl
在Vim之外解决这个问题,这样我就可以使用功能更强大的perl正则表达式而不是GNU子集。您可以将它映射到
中的一个键

ack-l'pattern'| xargs perl-pi-E's/pattern/replacement/g'
解释
ack
是一个很棒的命令行工具,它混合了
grep
find
和完整的Perl正则表达式(不仅仅是GNU子集)。它是用纯Perl编写的,速度快,有匹配高亮显示,在Windows上工作,比传统的命令行工具对程序员更友好。使用
sudo-apt-get-Install-ack-grep
在Ubuntu上安装

xargs
是一个旧的Unix命令行工具。它从标准输入读取项,并执行指定的命令,然后执行为标准输入读取的项。因此,基本上,
ack
生成的文件列表被附加到
perl-pi-E的s/pattern/replacement/g'
命令的末尾

perl-pi-E
Perl是一种编程语言

-p
选项使Perl在程序周围创建一个循环,循环遍历文件名参数

-i
选项使Perl就地编辑文件。您可以修改此选项以创建备份

-E
选项使Perl执行指定为程序的一行代码

有关Perl命令行选项的更多信息,请参阅。有关Perl的更多信息,请参阅。

我使用MacVim(在shell中用
mvim
激活)。我将
ack
的结果传输到
mvim

mvim -f $(ack -l $@)
然后在MacVim中,我使用
bufdo
搜索/替换:

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

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

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

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

:args `ag -l User app/`
:argdo %s/, :expire.*)/)/gec | w

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

所以你可以用

:Ack pattern
:cdo s/pattern/newpattern/g

假设您执行了类似于
:QFDo v/skipPat/s/Pat/Rep/gce的操作,并且在quickfix窗口上有一个很大的缓冲区列表。然后在第一个文件中,您注意到您错误地键入了替换字符串Rep。键入
Ctrl-c
不会停止命令,但只有当前行上的replace命令—它将永远需要
Ctrl-c
每个缓冲区上的y行匹配。是否有任何技巧可以抓住
Ctrl-c
ESC
键,并在上面的函数上断开
for
语句?另请参见基于上面的答案,它给出了源代码。do vim-p$(ack-Qil“字符串匹配”)以使它们在各个选项卡中启动(如果这是您的事情!)+1由于未安装perl,我略推荐使用sed的解决方案:ack-l OLD_TEXT | xargs sed-I”“”s/OLD_TEXT/NEW_TEXT/g@Eric约翰逊,你为什么在这里用
-E
开关来切换
perl
?我看没有任何用处feature@sputnick,我只是习惯性地使用-E,所以我可以说-当然,e也可以工作。这会给我带来错误,除非我告诉ack只列出带有
-l
的文件,如下所示:
ack-l'pattern'| xargs perl-pi-e's/pattern/replacement/g'
@tommychheng如果没有perl,您如何运行ack?这应该是公认的答案。很好,谢谢!从vim 7.4开始,这是正确的答案。对于OP,有一个小小的调整::cfdo可能更合适。我可能遗漏了一些明显的东西,但我正在fedora上运行Vim 7.4,每当我尝试
:cdo
时,我都会得到
not和editor命令
,有什么想法吗?从帮助页面,您需要使用
+listcmds
功能编译Vim。它解释了丢失的命令吗?
:cdo s/pattern/newpattern/g | update
对我有用。
:Ack pattern
:cdo s/pattern/newpattern/g