Is it possible to both search recursively and with a given file pattern?

I am trying to do the equivalent of

find ./ -name "*.[c|h]" -exec grep -Hn PATTERN {} \;

Obviously you can use grep's -r flag, but when I specify a filename pattern such as:

grep -Hn -r PATTERN *.c

It only looks for *.c files in the current directory, not recursively.

I found this, but it does not talk about specifying filenames: Recursive grep vs find / -type f -exec grep {} \; Which is more efficient/faster?

2 Answers 2


At least with recent versions of GNU grep, you can use glob patterns in a --include argument

grep -Hrn --include="*.[ch]" PATTERN .

[In GNU grep > 2.11 you may omit the explicit starting directory . when using -r]

  • OSX grep also has that switch though patterns are matched to the full path as opposed to base name in GNU Commented Jan 12, 2017 at 17:54
  • I am using FreeBSD, this command just waits for STDIN, even though there is an --include flag. Commented Jan 12, 2017 at 18:21
  • @FarhanYusufzai that may be due to differences in how grep selects directories for the -r case: even in GNU grep, older versions require an explicit starting directory argument e.g. grep -Hrn --include="*.[ch]" PATTERN . Commented Jan 12, 2017 at 18:27

The *.c is expanded by the shell before grep is even run. With a suitably fancy shell (e.g. zsh, or bash with globstar set), one can pre-expand recursively via something like

grep bla **/*.[ch]

But that is a shell solution. Other solutions would be to look at the file detection support in such tools as the silver searcher, codesearch, ripgrep.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .