找到第一个匹配项后,是否有办法强制find命令立即停止?

#1 楼

通过GNU或FreeBSD find,可以使用-quit谓词:

find . ... -print -quit


NetBSD find等效项:

find . ... -print -exit


如果您要做的只是打印名称,并假设文件名不包含换行符,则可以执行以下操作:

find . ... -print | head -n 1


第一次比赛,但可能取决于时间安排和第二次比赛(或以后)的缓冲。基本上,当find消失时,它尝试输出某些内容时,它将以SIGPIPE终止,因为它已经读取并显示了输入的第一行。 find返回后的head命令。 find(非交互时)和head(仅当管道是脚本中的最后一个命令时)的Bourne Shell和AT&T实现不会,而使其在后台运行。如果您希望在任何外壳中看到该行为,则可以始终将以上内容更改为:文件,您可以尝试以下方法:

(find . ... -print &) | head -n 1


(将ksh替换为对该文件的处理方式)。

yash的副作用是返回退出状态,反映出虽然它已被杀死。

实际上,使用SIGPIPE信号而不是SIGTERM(printf代替find)将使某些外壳对此更加沉默死亡(但仍会返回非零退出状态)。

评论


如果有人需要测试是否有任何文件与谓词匹配,则只要在Bash和GNU Find中找到该谓词就立即停止,您可以执行以下操作:然后...它只是测试是否找到打印的东西。

– Tobia
2014-12-19 18:26



@Tobia最好将$(…)部分放在引号中,以防仅使用单括号([…])。

–phk
17年1月14日23:18



@phk除了我不使用单括号(因为它们太可怕了)之外,所以我不需要使用引号。

– Tobia
17年1月16日15:35

@Tobia,[是标准命令。该命令不是很可怕,而是类似Bourne的shell分析命令行的方式。 [[...]]是一个ksh构造,在各种shell中都有其自身的问题。例如,直到最近[[$(...)]]在zsh中都不起作用(您需要[[-n $(...)]])。除了zsh之外,您还需要在[[$ a = $ b]]中加上引号,[[=〜]]在实现之间,甚至在bash的版本之间以及某些bug中,都有不兼容的区别。就个人而言,我更喜欢[。

–StéphaneChazelas
17年1月16日15:55



什么是 ...? 。

– kyb
18年7月6日在17:23

#2 楼

find . -name something -print -quit


在打印完第一个匹配项后终止查找。

在特定数量的匹配项和打印结果后终止查找:

find . -name something -print | head -n 5


令人惊讶的是-尽管我不知道如何或为什么,但是head现在在5个匹配之后终止了字符串。

测试非常容易。只要让root进行查找就可以搜索成千上万个,甚至可能花费至少一分钟或更长的时间甚至更多的匹配结果。 (默认的head显示为10,使用“ head -n”指定行)。

请注意,该操作将在“ head -n”达到指定的换行符字符数后终止,因此任何包含多个换行符的匹配项字符将相应计数。

评论


我还观察到了这种“程序在完成输出之后终止程序”的现象,但是跨壳的情况却不一致。我认为这有其自身的问题-幸运的是,对于bash来说,答案已经在StackOverflow的Bash:bash脚本的头尾行为中。这为我提供了足够的信息,可以得出结论,该程序是否在后台终止还是继续在后台执行取决于其对SIGPIPE的响应-默认为killing。

–圣人
15年10月16日在16:04

我的意思是“跨越* programs // shells”,但显然unix.stackexchange.com宁愿我将其记录为第二条注释,而不是让我编辑第一条注释(这是stackexchange的,特定于站点的策略决定)。另外,我现在看到@Ruste在顶部评论了此效果,因为我直接回答了问题,这起初并没有帮助我...

–圣人
2015年10月16日在16:12



#3 楼

出于娱乐目的,这是Bash中的一个懒惰的find生成器。本示例在当前目录中的文件上生成一个环。阅读任何想要的内容,然后阅读kill %+(也许只有1个)


#4 楼

如果与标志-m一起使用,grep也会返回,因此与

find stuff | grep -m1 .


一起使用,它将在find打印的第一行之后返回。这与find stuff -print -quit | head -1之间的关系是,如果搜索足够快,则grep可能无法及时停止该进程(虽然实际上并不重要),而如果搜索时间较长,它将多余的时间来打印很多不需要的行。

它可以与busybox查找一起使用,尽管因为busybox grep也具有-m,所以它并不是真正需要的

find /tmp/stuff -exec "sh" "-c" "eval 'echo {}; { kill $PPID; }'" \;

关于查找过程的消息,已收到(通常)sigterm信号,但是此输出属于正在运行的外壳程序,而不是find命令,因此不会与命令输出混淆,这意味着管道或重定向将仅输出与find匹配的行。 br />