我如何更轻松地使用找到的文件名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
,它将在第三行打开该文件。它将为其找到的每个匹配项输出一个索引行。
我很确定这个脚本可以改进,但对于我的使用来说它工作得很好。
答案2
检查这是否有用:
文件=`grep -r foo /path/of/search/* | grep '罗杰'`
哪个项目=3
ThirdFile=`grep -r foo /路径/of/search/* |头-$WhichItem |尾巴-1`