I need to search the first 50 lines of every file in a directory and its subdirectories.

This will do the recursive part, but how do I limit to just the first 50 lines of each file?

grep -r "matching string here" .

Some of these files are huge, and I only want them to match in the first 50 lines. I'm trying to speed up the process by not searching megabytes of binary data in some files.

  • do you want to just know the files that match, or do you want to have just the matching string or do you want the matching string together with the filename? – gniourf_gniourf Oct 29 '13 at 19:13
  • If you just want the files that match:

    find . -type f -exec bash -c 'grep -q "matching string here" < <(head -n 50 "$1")' _ {} \; -printf '%p\n'


    find . -type f -exec bash -c 'grep -q "matching string here" < <(head -n 50 "$1") && printf '%s\n' "$1"' _ {} \;
  • If you only want the matching strings:

    find . -type f -exec head -n 50 {} \; | grep "matching string here"

    or, better,

    find . -type f -exec head -q -n 50 {} + | grep "matching string here"
  • And if you want both:

    find . -type f -exec bash -c 'mapfile -t a < <(head -n 50 "$1" | grep "matching string here"); printf "$1: %s\n" "${a[@]}"' _ {} \;


  • Could be slightly easier with sed instead of the combo head--grep.
  • Let me stress that all three methods are 100% safe regarding file names that may contain funny symbols (spaces, newlines, etc.).
  • In two of these methods, I'm assuming you have a decently recent version of bash.
  • You could use -exec ... + in each method, but then you'll have to code your inner loop yourself! (trivial exercise left to the reader). This might be very slightly more efficient if you have a gazillion files.
| improve this answer | |

If you need the grep output as in the original, you could do:

find . -type f | while read f; do 
  if head -n 50 "$f"|grep -s "matching string here"; then
    grep "matching string here" "$f" /dev/null 

If you only need the file names you can replace the 2nd grep with echo "$f".

| improve this answer | |

You'll need to combine a few different utilities to get the desired functionality. Use the find command to recurse the directories, find all files and execute the head command on each file found. The head command can be used to dump only the first 50 lines of each file. Finally, pipe the output to grep to search for your desired string.

find . -type f -exec head -n 50 {} ";" | grep "matching string here"

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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