How to use grep recursively within certain file extensions


grep is a great tool for searching between files and standard input in Linux and is capable of matching string patterns and Regex. However, sometimes you need to check which file types grep it looks for and has built-in flags to do just that.

By including only a few files in grep searches

by default, grep will look for all files in a given folder and its subfolders if you invoke it with recursive -r flag. This will collect everything, but if you only want certain extensions, the option you will want to use is --include.

the --include the flag says grep to include only files that match a certain pattern. If it is specified, grep will treat all inclusion flags as a whitelist. You can use it with any Linux glob character, such as wildcards to match everything, including a certain extension:

grep -inr --include \*.txt "foo" ~/folder

Note that this is avoided with a forward slash \ because filenames may contain asterisks. You can also specify multiples --include flag, for example, searching for all HTML, JS and CSS source files in a wwwroot:

grep -inr --include \*.html --include \*.css --include \*.js "foo" ~/folder

Similarly you can also exclude certain filenames, which will still match everything but the glob, by acting as a blacklist on top of the existing configuration:

grep -inr --exclude \*.txt "foo" ~/folder

There is also a flag to exclude entire directories at once:

grep -inr --exclude-dir config "foo" ~/folder

Using find instead

Alternatively, if you prefer to use the find utility to search through files, to which you can link it grep using tubes and xargs. find it can perform pattern and regex searches and has many benefits, including the ability to easily filter files based on metadata such as size, creation and modification date, and other Linux identifiers.

The command is a bit dull, as you will have to use it -print0 at the end of find to print a single line list, then pass it to xargs -0 Other grep from there.

 find ./ -type f -iname "*.txt" -print0 | xargs -0 grep "foo"