1

如何通过管道传输到git grep要搜索特定模式的文件列表?
具体来说,我这样做:

git grep -l 'string to search' 

git grep我想对上一次搜索的结果文件 再做一次。

git grep -l -e 'string to search' --and -e 'another string'  

没有给出任何结果,但我知道有匹配项

正在做

git grep -l 'string to search' | git grep -l 'another string'

给出相同的结果git grep -l 'another string'

4

2 回答 2

2

您的第二个git grep不会将第一个的结果作为参数,它只输出它应该输出的内容,而不管第一个命令如何。

用一个简单的 bash grep 替换它,它应该可以

git grep -l 'string to search' | grep 'another string'
于 2019-10-05T20:46:55.170 回答
2

TL;博士

您不能通过管道传输名称,但可以将名称(作为路径规范)提供给两个git grep命令之一。

(奇怪的是,--and应该首先做你想做的事——我只是在回答如何在没有 . 的情况下做到这一点的问题--and。)

中长

目前尚不清楚您想要什么结果,但假设您想要的是:

  • 对于(一些提交|一些提交集|索引|工作树)中的每个文件

    • 如果文件包含模式 1

    • 并且该文件包含同一文件中的其他任何位置(不一定在同一行)模式2

    • 然后列出文件名

有两种明显的方法可以尝试实现这一目标,但其中一种方法不起作用,因为 Git 不会跨换行符匹配。1 所以我们只剩下另一个明显的方法:

  • 首先,用于git grep -l生成与第一个表达式匹配的文件列表。
  • 然后,用于git grep -l生成与第二个表达式匹配的文件列表,可选地,仅从第一个生成的文件开始git grep

要将它们组合为and操作,您有一个相当明显的选择,即使用两个git grep -l输出中的一个作为另一个的一系列路径名参数git grep。但是请注意,在分隔它们的后面git grep需要pathspec参数,而不是路径参数--(有关详细信息,请参阅文档)。这意味着如果您的任何文件名中包含 pathspec 元字符,那么这个简单的 shell 扩展可能会失败。验证第一个grep实际上列出了一些文件,但将它们组合成一个 bash 样式命令,这也可能是一个好主意:

git grep -l pattern2 -- $(git grep -l pattern1)

通常可能就足够了。

要将上述两者组合为一个or操作(列出包含任一模式的文件),最简单的方法是使用一个git grep与多个模式。但是请注意,您可以运行多个git grep -l操作并将生成的文件名定向到临时文件,然后使用类似程序comm报告每组结果的共同点和独特点。(这假设您comm在命令行解释器工具箱中有。)使用comm还可以解决带有特殊文件名(如(top)file.corgot*you.sh或其他)的路径规范问题。


1如果 Git确实跨换行符匹配,您可以使用扩展模式或 Perl 模式:(foo(.|\n)*bar)|(bar(.|\n)*foo)以允许在其他两个模式foo和之间任意文本bar,其中任一模式按任意顺序排列。

于 2019-10-06T02:38:53.387 回答