Answers:
使用GNU或FreeBSD find
,您可以使用-quit
谓词:
find . ... -print -quit
find
相当于NetBSD :
find . ... -print -exit
如果您仅打印名称,并假设文件名不包含换行符,则可以执行以下操作:
find . ... -print | head -n 1
find
在第一场比赛之后,这不会停止,但是可能取决于第二场比赛(或以后)的时间安排和缓冲时间。基本上,find
当它试图输出某些head
已经消失的东西时,将以SIGPIPE终止,因为它已经读取并显示了输入的第一行。
请注意,并不是所有的外壳程序find
在head
返回后都会等待该命令。ksh
(当非交互时)和yash
(仅当管道是脚本中的最后一个命令时)的Bourne shell和AT&T实现不会,而使其在后台运行。如果您希望在任何shell中看到该行为,则可以始终将以上内容更改为:
(find . ... -print &) | head -n 1
如果您不只是打印找到的文件的路径,还可以尝试以下方法:
find . ... -exec sh -c 'printf "%s\n" "$1"; kill "$PPID"' sh {} \;
(替换printf
为该文件要执行的操作)。
这样做的副作用是find
返回退出状态,反映出已被杀死的事实。
实际上,使用SIGPIPE信号而不是SIGTERM(kill -s PIPE
而不是kill
)将使某些shell对于该死亡更为沉默(但仍会返回非零退出状态)。
if [[ $(find ... -print -quit) ]]; then ...
它只是测试是否查找打印出的任何东西。
$(…)
在仅使用单括号([ … ]
)的情况下将零件引号引起来。
[
是标准命令。该命令不是很可怕,而是类似Bourne的shell解析命令行的方式。[[...]]
是一个ksh构造,在各种shell中都有其自身的问题。例如,直到最近[[ $(...) ]]
才可用zsh
(您需要[[ -n $(...) ]]
)。除了中的zsh
,您需要用中的引号[[ $a = $b ]]
,[[ =~ ]]
在实现之间,甚至在bash的版本之间以及某些错误中,都有不兼容的区别。我个人更喜欢[
。
...
?。
find . -name something -print -quit
打印完第一个匹配项后终止查找。
在特定数量的匹配并打印结果后终止查找:
find . -name something -print | head -n 5
出乎意料的是,尽管现在我不知道如何或为什么,head现在在5个匹配项后终止了字符串。
测试非常容易。只需让根目录下的搜索成为可能,这将导致成千上万次,甚至可能需要至少一分钟或更长时间才能进行更多的匹配。但是当通过管道传递到“ head”中时,“ find”将在head中定义的指定行数之后终止(默认head显示10,使用“ head -n”指定行)。
请注意,这将在“ head -n”达到指定的换行符字符计数后终止,因此包含多个换行符的任何匹配项都将相应计数。
出于娱乐目的,这是Bash中的一个懒惰的find生成器。本示例在当前目录中的文件上生成一个环。然后阅读您想要阅读的内容kill %+
(也许只有1个)
#!/usr/bin/env bash
unset -v files n
trap 'kill "$x_PID"' EXIT
coproc x while :; do
find . -type f -maxdepth 1 -exec sh -c "$(</dev/fd/3)" _ {} +
done 4<&0 <<\EOF 3<&0 <&4-
for x; do
read -r _
printf '%s\0' "$x"
done
EOF
while
echo >&${x[1]}
IFS= read -rd '' -u "$x" 'files[n++]'
do
printf '%q ' "${files[@]}"
echo
sleep .2
done
如果与flag -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; }'" \;
这将吐出一条有关find进程已收到(通常)sigterm信号的消息,但是此输出属于正在运行的shell,而不是find命令,因此不会与命令输出混淆,这意味着管道或重定向将仅输出该行通过查找匹配。