我正在使用带有以下参数的 grep 递归搜索目录,希望只返回第一个匹配项。不幸的是,它返回的不止一个——实际上是我上次查看时返回的两个。似乎我有太多的争论,尤其是没有得到想要的结果。:-/
# grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/directory
返回:
Pulsanti Operietur
Pulsanti Operietur
也许 grep 不是最好的方法?你告诉我,非常感谢。
我正在使用带有以下参数的 grep 递归搜索目录,希望只返回第一个匹配项。不幸的是,它返回的不止一个——实际上是我上次查看时返回的两个。似乎我有太多的争论,尤其是没有得到想要的结果。:-/
# grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/directory
返回:
Pulsanti Operietur
Pulsanti Operietur
也许 grep 不是最好的方法?你告诉我,非常感谢。
-m 1
表示返回任何给定文件中的第一个匹配项。但它仍会继续在其他文件中搜索。此外,如果在同一行中有两个或更多匹配,则将显示所有这些。
head -1
来解决这个问题:grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -1
-o, --only-matching, print only the matched part of the line (instead of the entire line)
-a, --text, process a binary file as if it were text
-m 1, --max-count, stop reading a file after 1 matching line
-h, --no-filename, suppress the prefixing of file names on output
-r, --recursive, read all files under a directory recursively
您可以将grep
结果head
与stdbuf结合使用。
请注意,为了确保在第 N 次匹配后停止,您需要使用stdbuf
以确保grep
不缓冲其输出:
stdbuf -oL grep -rl 'pattern' * | head -n1
stdbuf -oL grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -n1
stdbuf -oL grep -nH -m 1 -R "django.conf.urls.defaults" * | head -n1
一旦head
消耗了 1 行,它就会终止并grep
接收,因为它在消失SIGPIPE
时仍然输出一些东西到管道。head
这假设没有文件名包含换行符。
我的 grep-a-like 程序ack
有一个-1
选项,可以在任何地方找到第一个匹配项时停止。它也支持-m 1
@mvp 所指的内容。我把它放在那里是因为如果我正在搜索一棵大树的源代码以找到我知道只存在于一个文件中的东西,那么没有必要找到它并且必须按 Ctrl-C。
如果要在当前目录中出现特定单词时要打印整行和文件名,则可以使用以下命令。
grep -m 1 -r "Not caching" * | head -1
对于像我一样登陆这里的任何人,对于为什么--max-count
在采取行动时似乎没有工作感到困惑stdin
......
TL;DR -找到匹配项后不会--max-count n
停止,它会在找到行上的所有匹配项后停止。n
n
(而且stdin
,即使它只是一个字符串,也算作一行。)
尽管事实上,zsh 5.8
至少在man grep
中以这种方式描述了该选项,但这是正确的:
-m num, --max-count=num
Stop reading the file after num matches.
更长的解释
就我而言,我试图仅获取相对路径的第一部分:
> echo "some/path/here" | grep -E -o -m 1 '[^\/]+'
当它把我还给我的时候很困惑
some
path
here
感谢上面@harperville 的评论,我终于明白了:这不是关于输出,而是关于输入。
确实,当我尝试
> echo "some/path/here\nanother/path/there" | grep -E -o -m 1 '[^\/]+'
我得到了与上面相同的结果(即,仅\n
在第二个示例中之前的部分)。
笔记
对于那些不太熟悉的人grep
:
-E
( --extended-regexp
) 告诉它使用“扩展的”正则表达式,即您在大多数其他编程语言中习惯使用的正则表达式。“扩展”和“基本”之间的区别并不大——只是你需要在你的正则表达式中转义哪些字符——但作为主要是 TS 和 Python 开发人员的人,我总是使用-E
这种方式,因为我不需要思考关于它。(专业提示:添加alias grep="grep -E"
到您的.zshrc
,您将永远不必再担心它!)-o
( --only-matching
) 告诉它只打印匹配项,而不是找到匹配项的每一行。-m n
( --max-count n
) 将其限制为搜索n
行。(如果你已经读到这里,那么你显然已经知道了!)阅读 grep 手册(man grep),这是查找与扩展正则表达式的第一个匹配项的最少命令。获取我笔记本电脑中的以太网名称不是 eth0 的示例!
$ ifconfing | grep -E -o -m 1 "^[a-z0-9]+"
说明:-E 表示扩展正则表达式,-o 只返回匹配项,-m 1 只看一行
单个衬里,使用find
:
find -type f -exec grep -lm1 "PATTERN" {} \; -a -quit