Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Maybe it's a bit strange - and maybe there are other tools to do this but, well..

I am using the following classic bash command to find all files which contain some string:

find . -type f | xargs grep "something"

I have a great number of files, on multiple depths. first occurence of "something" is enough for me, but find continues searching, and takes a long time to complete the rest of the files. what i would like to do is something like a "feedback" from grep back to find so that find could stop searching for more files. is such a thing possible?

share|improve this question

migrated from stackoverflow.com Dec 9 '11 at 15:51

This question came from our site for professional and enthusiast programmers.

add comment

3 Answers 3

up vote 13 down vote accepted

Simply keep it within the realm of find:

find . -type f -exec grep "something" {} \; -quit

This is how it works:

The -exec will work when the -type f will be true. And because grep returns 0 (success/true) when the -exec grep "something" has a match, the -quit will be triggered.

share|improve this answer
add comment
find -type f | xargs grep e | head -1

does exactly that: when the head terminates, the middle element of the pipe is notified with a 'broken pipe' signal, terminates in turn, and notifies the find. You should see a notice such as

xargs: grep: terminated by signal 13

which confirms this.

share|improve this answer
    
+1 for explanation and the alternative, though the other answer seems more elegant to me, since it is more self-sufficient –  hello_earth Jan 16 '13 at 9:21
add comment

To do this without changing tools: (I love xargs)

#!/bin/bash
find . -type f |
    # xargs -n20 -P20: use 10 parallel processes to grep files in batches of 20
    # grep -m1: show just on match per file
    # grep --line-buffered: multiple matches from independent grep processes
    #      will not be interleaved
    xargs -P10 -n20 grep -m1 --line-buffered "$1" 2> >(
        # Error output (stderr) is redirected to this command.
        # We ignore this particular error, and send any others back to stderr.
        grep -v '^xargs: .*: terminated by signal 13$' >&2
    ) |
    # Little known fact: all `head` does is send signal 13 after n lines.
    head -n 1
share|improve this answer
    
+1 never knew xargs would have such multitasking capabilities - thanks for other comments as well! :) –  hello_earth Feb 5 at 10:53
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.