解析grep输出并运行带有结果

时间:2016-08-30 22:47:41

标签: vim grep string-parsing

我目前正在使用命令行来grep源树中的模式。 grep输出行的格式为:

path/to/a/file.java:123: some text here

如果我想在grep输出中指定的位置打开文件,我必须手动输入vim命令:

$ vim +123 path/to/a/file.java

是否有一种更简单的方法可以让我使用原始grep输出并解析相关组件并在#行上为文件运行vim。

我对命令行解决方案感兴趣。我知道我可以在vim里面做greps。

由于

5 个答案:

答案 0 :(得分:2)

file-line插件正是您想要的。安装完成后,您只需运行

即可
vim path/to/a/file.java:123

答案 1 :(得分:1)

您只需从Vim本身运行grep并从quickfix列表/窗口中受益:

:grep -Rn foo **/*.h
:cw
(scroll around)
<CR>

您可以将grep输出传递给Vim以获得相同的好处:

$ vim -q <(grep -Rn foo **/*.h)
:cw
(scroll around)
<CR>

,如果您已经在Vim中,可以将grep的输出插入缓冲区并使用gF跳转到右侧的右侧文件:

:r !grep -Rn foo **/*.h
(scroll around)
gF
来自你的shell

$ vim <(grep -Rn foo **/*.h)
(scroll around)
gF

,如果您刚刚运行grep,则可以重复使用它:

$ vim <(!!)
(scroll around)
gF

,如果您知道history中的号码:

$ vim <(!884)
(scroll around)
gF

答案 2 :(得分:0)

> vim $(cat the.file | grep xxx)

将evauluates $() - 在.file中找到xxx然后将xxx传递给vim

也可以用反引号``:

> vim `cat the.file | grep xxx`

答案 3 :(得分:0)

试试这个:

grep -nr --null pattern | { IFS= read -rd "" f; IFS=: read -d "" n match; vim +$n "$f" </dev/tty; }

greppattern进行递归搜索。对于它找到的第一个文件,vim+linenum参数启动,以使您进入感兴趣的行。

此方法使用NUL分离的i / o。它应该对所有文件名都是安全的,即使是那些包含空格或其他困难字符的文件名。

这是在GNU工具(Linux)上测试的。它也可以在BSD / OSX上运行。

多行版本

对于那些喜欢分布在多行的命令的人:

grep -nr --null pattern | {
   IFS= read -rd "" f
   IFS=: read -d "" n match
   vim +$n "$f" </dev/tty
}

便利功能

因为上面的命令很长,所以可能想把它放在shell函数中:

vigrep() { grep -nr --null "$1" | { IFS= read -rd "" f; IFS=: read -d "" n match; vim +$n "$f" </dev/tty; }; }

一旦定义了它,它就可以用来搜索包含任何模式的文件。例如:

vigrep 'some text here'

要将vigrep定义为永久定义,请将其放在~/.bashrc文件中。

如何运作

  • grep -nr --null pattern

    -r告诉grep以递归方式搜索。

    -n告诉grep返回匹配的行号。

    -null告诉grep使用NUL分离的输出

    pattern是要搜索的正则表达式。

  • IFS= read -rd "" f

    这将读取输入的第一个NUL分隔部分(将是文件名)并将其分配给shell变量f

  • IFS=: read -d "" n match

    这将使用:作为单词分隔符读取下一个NUL分隔的输入部分。第一个单词(行号)分配给shell变量n。该行的其余部分将被忽略。

  • vim +$n "$f" </dev/tty

    这会使用终端vim在文件$n的行号$f上启动/dev/tty作为输入。

    通常,在运行vim时,确实希望vim接受来自键盘的输入。这就是为什么,对于这种情况,我们硬编码来自/dev/tty的输入。

使用剪切和粘贴启动vim

启动以下内容并将grep -n输出行剪切并粘贴到其中:

IFS=: read f n rest; vim +$n "$f"

read命令将等待标准输入上的一行。它期望的输入类型如下:

path/to/a/file.java:123: some text here

因为IFS=:,它会在冒号上划分行,并将文件名分配给shell变量f,将行号分配给shell变量n。完成后,它将启动vim命令。

如果需要,此命令也可以保存为shell函数:

grvim() { IFS=: read f n rest; vim "+$n" "$f"; }

答案 4 :(得分:0)

我在.bashrc

中有此功能
grep_edit(){
    grep "$@" | sed 's/:/ +/;s/:/ /';
}

因此,输出的格式为:

path/to/a/file.java +123 some text here

然后我可以直接使用

$ vi path/to/a/file.java +123

注意:我也听说过file-line plugin,但我不确定它如何与netrw插件一起使用。

e.g。 vi可以使用以下语法打开远程文件:

vi scp://root@remote-system//var/log/daemon.log

但如果这不是问题,那么你可以更好地使用文件行插件。