Is there a way to force the find command to stop right after finding the first match?
Best Answer
With GNU or FreeBSD find, you can use the -quit predicate:
find . ... -print -quit
The NetBSD find equivalent:
find . ... -print -exit
If all you do is printing the name, and assuming the filenames don't contain newline characters, you could do:
find . ... -print | head -n 1
That will not stop find after the first match, but possibly, depending on timing and buffering upon the second match or (much) later. Basically, find will be terminated with a SIGPIPE when it tries to output something while head is already gone because it has already read and displayed the first line of input.
Note that not all shells will wait for that find command after head has returned. The Bourne shell and AT&T implementations of ksh (when non-interactive) and yash (only if that pipeline is the last command in a script) would not, leaving it running in background. If you'd rather see that behaviour in any shell, you could always change the above to:
(find . ... -print &) | head -n 1
If you're doing more than printing the paths of the found files, you could try this approach:
find . ... -exec sh -c 'printf "%s\n" "$1"; kill "$PPID"' sh {} \;
(replace printf with whatever you would be doing with that file).
That has the side effect of find returning an exit status reflecting the fact that it was killed though.
Actually, using the SIGPIPE signal instead of SIGTERM (kill -s PIPE instead of kill) will cause some shells to be more silent about that death (but would still return a non-zero exit status).
The problem is that the default type of regex's used by find is emacs-style. Find's documentation for emacs style regexes doesn't include the \{n,\} construction--leading me to believe that it isn't supported in find's implemenation of emacs-style regular expressions. The emacs-wiki lists this as valid, however it is possible that this wasn't always the case.
I found that your regex produced output if you do this:
Best Answer
With GNU or FreeBSD
find
, you can use the-quit
predicate:The NetBSD
find
equivalent:If all you do is printing the name, and assuming the filenames don't contain newline characters, you could do:
That will not stop
find
after the first match, but possibly, depending on timing and buffering upon the second match or (much) later. Basically,find
will be terminated with a SIGPIPE when it tries to output something whilehead
is already gone because it has already read and displayed the first line of input.Note that not all shells will wait for that
find
command afterhead
has returned. The Bourne shell and AT&T implementations ofksh
(when non-interactive) andyash
(only if that pipeline is the last command in a script) would not, leaving it running in background. If you'd rather see that behaviour in any shell, you could always change the above to:If you're doing more than printing the paths of the found files, you could try this approach:
(replace
printf
with whatever you would be doing with that file).That has the side effect of
find
returning an exit status reflecting the fact that it was killed though.Actually, using the SIGPIPE signal instead of SIGTERM (
kill -s PIPE
instead ofkill
) will cause some shells to be more silent about that death (but would still return a non-zero exit status).