git 搜索文件名
git grepping on filenames
如何通过管道传输到 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'
相同的结果
你的第二个 git grep
没有将第一个的结果作为参数,它只输出它应该输出的内容,而不考虑第一个命令。
用一个简单的 bash grep 替换它,它应该可以
git grep -l 'string to search' | grep 'another string'
TL;DR
您不能管道名称,但您可以提供名称(作为路径规范)到两个git grep
命令。
(奇怪的是,--and
一开始就应该完成你想要的——我只是回答没有 --and
如何做到的问题。)
中等长度
不清楚您想要什么结果,但假设您想要的是:
对于(一些提交 | 一些提交集 | 索引 | 工作树)中的每个文件
如果文件包含模式 1
and 文件包含,同一文件中的其他任何地方(不一定在同一行)模式 2
然后列出文件名
有两种比较明显的方法可以尝试实现这一点,但其中一种不起作用,因为 Git 无法跨换行匹配。1所以我们剩下另一个明显的方法:
- 首先,使用
git grep -l
生成与第一个表达式匹配的 文件列表 。
- 然后,使用
git grep -l
生成匹配第二个表达式的 文件列表 ,可选地,仅从第一个 git grep
生成的文件开始.
要将它们组合为 和 操作,您有一个相当明显的选择,即使用两个 git grep -l
输出中的一个作为另一个的一系列路径名参数git grep
。但是请注意,git grep
在分隔它们的 --
之后采用 pathspec 参数,而不是路径 name 参数(有关详细信息,请参阅 the documentation)。这意味着如果您的任何文件名中包含路径规范元字符,这个简单的 shell 扩展可能会失败。验证第一个 grep
实际上列出了一些文件,但将它们组合成一个 bash 样式命令可能也是一个好主意:
git grep -l pattern2 -- $(git grep -l pattern1)
通常就足够了。
要将以上两者组合为 或 操作(列出包含任一模式的文件),最简单的方法是只使用一个 git grep
和多个模式。但是请注意,您可以 运行 多次 git grep -l
操作,将生成的文件名定向到一个临时文件,然后使用 comm
之类的程序来报告每组文件的共同点和独特点结果。 (假设您的命令行解释器工具箱中有 comm
。)使用 comm
还可以解决特殊文件名(如 (top)file.c
或 got*you.sh
或其他名称)的路径规范问题.
1如果 Git did 跨换行匹配,您可以使用扩展或 Perl 模式:(foo(.|\n)*bar)|(bar(.|\n)*foo)
以允许在其他两个模式 foo
和 bar
之间的任意文本,其中任一模式的顺序都可以。
如何通过管道传输到 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'
你的第二个 git grep
没有将第一个的结果作为参数,它只输出它应该输出的内容,而不考虑第一个命令。
用一个简单的 bash grep 替换它,它应该可以
git grep -l 'string to search' | grep 'another string'
TL;DR
您不能管道名称,但您可以提供名称(作为路径规范)到两个git grep
命令。
(奇怪的是,--and
一开始就应该完成你想要的——我只是回答没有 --and
如何做到的问题。)
中等长度
不清楚您想要什么结果,但假设您想要的是:
对于(一些提交 | 一些提交集 | 索引 | 工作树)中的每个文件
如果文件包含模式 1
and 文件包含,同一文件中的其他任何地方(不一定在同一行)模式 2
然后列出文件名
有两种比较明显的方法可以尝试实现这一点,但其中一种不起作用,因为 Git 无法跨换行匹配。1所以我们剩下另一个明显的方法:
- 首先,使用
git grep -l
生成与第一个表达式匹配的 文件列表 。 - 然后,使用
git grep -l
生成匹配第二个表达式的 文件列表 ,可选地,仅从第一个git grep
生成的文件开始.
要将它们组合为 和 操作,您有一个相当明显的选择,即使用两个 git grep -l
输出中的一个作为另一个的一系列路径名参数git grep
。但是请注意,git grep
在分隔它们的 --
之后采用 pathspec 参数,而不是路径 name 参数(有关详细信息,请参阅 the documentation)。这意味着如果您的任何文件名中包含路径规范元字符,这个简单的 shell 扩展可能会失败。验证第一个 grep
实际上列出了一些文件,但将它们组合成一个 bash 样式命令可能也是一个好主意:
git grep -l pattern2 -- $(git grep -l pattern1)
通常就足够了。
要将以上两者组合为 或 操作(列出包含任一模式的文件),最简单的方法是只使用一个 git grep
和多个模式。但是请注意,您可以 运行 多次 git grep -l
操作,将生成的文件名定向到一个临时文件,然后使用 comm
之类的程序来报告每组文件的共同点和独特点结果。 (假设您的命令行解释器工具箱中有 comm
。)使用 comm
还可以解决特殊文件名(如 (top)file.c
或 got*you.sh
或其他名称)的路径规范问题.
1如果 Git did 跨换行匹配,您可以使用扩展或 Perl 模式:(foo(.|\n)*bar)|(bar(.|\n)*foo)
以允许在其他两个模式 foo
和 bar
之间的任意文本,其中任一模式的顺序都可以。