你能够批量编辑grep返回的所有文件吗?

64

我想批量编辑 grep 返回的大量文件。(我知道,我应该学会更好地使用 sed)。

如果我执行以下命令:

grep -rnI 'xg_icon-*'

我该如何将所有这些文件导入到vi中?


但是vi只能同时打开一个文件,对吗? - paolo granada lim
不,你可以同时打开多个文件。命令:next和:prev将循环遍历参数列表。在实际的vi中,您必须在更改文件之前保存。使用Vim,您可以“:set hidden”以在不需要先保存的情况下更改缓冲区,但如果尝试退出而未保存更改,则仍会收到警告。此外,Vim具有:bnext和:bprev命令,可浏览缓冲区列表,该列表是参数列表的超集。 - jamessan
另外要提到的一件事是,如果你正在使用vim编辑大量文件,可以使用类似BufExplorer vim插件的工具来查看你打开了哪些缓冲区,并快速地在它们之间切换。 - Benj
6个回答

93

最简单的方法是让grep仅返回匹配模式的文件名(-l而不是-n)。在子shell中运行它,并将结果提供给Vim。

vim $(grep -rIl 'xg_icon-*' *)

1
还要注意,当标准输入来自管道时,vim 不喜欢它,因此上面的命令比 'grep -rIl ... | vim' 好得多。 - Kaleb Pederson
1
当您使用 vim - 调用它时,Vim 对标准输入感到满意。 - a paid nerd
1
@Kaleb 当vim从管道读取内容时,它的表现非常出色。但在这种情况下,不要忘记调用xargs。当管道中填充的是内容而不是文件名时,这位有经验的程序猿回答了你的提问:不要忘记加上破折号。 - Luc Hermitte
7
通常在使用 grep ... 命令得到正确的结果后,我会执行 vi $(!! -l) 命令。这在所有现代 Bash 上都可以正常工作,但据我记得在 MSysGit/Cygwin 上可能不行。 - Wernight
@Wernight,那是A+。 - pattivacek

27

一个不错的通用解决方案是使用xargs将像grep这样的进程的标准输出转换为参数列表。

如下:

grep -rIl 'xg_icon-*' | xargs vi

对我来说非常有帮助的答案,尤其是它适用于不是“vi”的程序。(我们中的一些人不属于那个部落,但大多数这种类型的问题都明确指向那个方向。) - Chris Krycho
5
在我的Mac上(在终端中),使用vim执行这个命令后,我的终端的标准输入出现了一些奇怪的问题。其他解决方案没有这个问题。字符无法正常显示等。您有什么想法? - D. Ben Knoble

8

如果您使用vim和-p选项,它将在一个标签页中打开每个文件,并且您可以使用gt或gT甚至是鼠标(如果终端支持)在它们之间切换。


8

你可以不需要对grep输出进行任何处理就能完成任务!这甚至可以让你跳转到正确的行(使用:help quickfix命令,例如:cn:cw)。所以,如果你正在使用bash或zsh:

vim -q <(grep foo *.c)

1
vim -q -c copen <(grep foo *.c) 看起来更好。 - lkraav

2

如果你想编辑的内容在所有文件中都相似,那么手动使用vi编辑没有意义(尽管vi也可以脚本化)。假设情况是这样的,因为你从未提到你要编辑什么内容。

grep -rnI 'xg_icon-*' | while read FILE
do
    sed -i.bak 's/old/new/g' $FILE # (or other editing commands, eg awk... )
done

1
vi `grep -l -i findthisword *`

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接