从 grep 输出自动完成

从 grep 输出自动完成

我如何更轻松地使用找到的文件名grep作为参数vim

$ grep -r foo *
lib/beatles/john.c
lib/pantera/phil.c
lib/pinkfloyd/roger.c
lib/pinkfloyd/richard.c
lib/whitestripes/elephant/jack.c

$ vim lib/pinkfloyd/roger.c

要使用 Bash 自动完成,我需要输入皮罗\t\t\t\t\t 因为许多其他文件匹配。有没有更简单的方式来表达“给我找到的第三个文件?”也许是这样的:

$ vim $3        // Third line
$ vim 'roger'   // Only line with string 'roger'
$ vim TabTabTab // Each Tab completes a different filename from grep

我确实使用 Tmux,并且我知道我可以向上选择文件名,然后粘贴它。但即使作为 VIM 用户,这仍然有点笨拙。一定会有更好的办法!

请注意,我并不是在寻找解决方案编写 grep 输出的脚本,相反,这是我在使用 VIM grep 和打开文件时手动使用的东西。

编辑:我正在寻找一种通用的解决方案,而不是始终针对“roger”或始终针对第三项的解决方案。

答案1

我编写了一个脚本来递归地查找模式,然后我可以选择其中一个匹配项,这样 vim 将在该行中打开该文件。我称之为vgrep(vim grep,尽管它也在awk其中使用)。下面是它的代码:

#!/bin/bash
my_grep() {
        grep -Rn -I --color=auto --exclude-dir={.svn,.git} --exclude={tags,cscope.out} "$@" . 2>/dev/null
}
my_grep_color() {
        grep -Rn -I --color=always --exclude-dir={.svn,.git} --exclude={tags,cscope.out} "$@" . 2>/dev/null
}

awk '{
    print NR, $0
}' <(my_grep_color "$@")

awk '{
    lines[NR]=$1;
}

END{
    printf "Enter index: "
    getline num < "-";
    split(lines[num], s, ":")
    system("vim "s[1]" +"s[2])
}' <(my_grep "$@")

我调用grep两次只是为了突出显示我的比赛,您可以更改它,这样它只会被调用一次,但您将失去突出显示。

用法:

假设你想在其中有单词“Foo”的行中打开vim,你可以这样使用它:vgrep Foo

如果有一个类似 foobar 的文件:

a b c
Bar
e f Foo g
h i

vgrep将输出:

1 ./foobar:3 e f Foo g
Enter index: 

所以你可以输入1+ enter,它将在第三行打开该文件。它将为其找到的每个匹配项输出一个索引行。

我很确定这个脚本可以改进,但对于我的使用来说它工作得很好。


另外,考虑使用标签范围如果您正在与C/C++.

答案2

检查这是否有用:

文件=`grep -r foo /path/of/search/* | grep '罗杰'`

哪个项目=3

ThirdFile=`grep -r foo /路径/of/search/* |头-$WhichItem |尾巴-1`

相关内容