How can I grep recursively, but only in files with certain extensions?
GrepGrep Problem Overview
I'm working on a script to grep
certain directories:
{ grep -r -i CP_Image ~/path1/;
grep -r -i CP_Image ~/path2/;
grep -r -i CP_Image ~/path3/;
grep -r -i CP_Image ~/path4/;
grep -r -i CP_Image ~/path5/; }
| mailx -s GREP [email protected]
How can I limit results only to extensions .h
and .cpp
?
Grep Solutions
Solution 1 - Grep
Just use the --include
parameter, like this:
grep -inr --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP email@domain.com
That should do what you want.
To take the explanation from HoldOffHunger's answer below:
-
grep
: command -
-r
: recursively -
-i
: ignore-case -
-n
: each output line is preceded by its relative line number in the file -
--include \*.cpp
: all *.cpp: C++ files (escape with \ just in case you have a directory with asterisks in the filenames) -
./
: Start at current directory.
Solution 2 - Grep
Some of these answers seemed too syntax-heavy, or they produced issues on my Debian Server. This worked perfectly for me:
grep -r --include=\*.txt 'searchterm' ./
...or case-insensitive version...
grep -r -i --include=\*.txt 'searchterm' ./
-
grep
: command -
-r
: recursively -
-i
: ignore-case -
--include
: all *.txt: text files (escape with \ just in case you have a directory with asterisks in the filenames) -
'searchterm'
: What to search -
./
: Start at current directory.
Source: PHP Revolution: How to Grep files in Linux, but only certain file extensions?
Solution 3 - Grep
grep -rnw "some thing to grep" --include=*.{module,inc,php,js,css,html,htm} ./
Solution 4 - Grep
Use:
find . -name '*.h' -o -name '*.cpp' -exec grep "CP_Image" {} \; -print
Solution 5 - Grep
There isn't any -r
option on HP and Sun servers, but this way worked for me on my HP server:
find . -name "*.c" | xargs grep -i "my great text"
-i
is for case insensitive search of string.
Solution 6 - Grep
Since this is a matter of finding files, let's use find
!
Using GNU find you can use the -regex
option to find those files in the tree of directories whose extension is either .h
or .cpp
:
find -type f -regex ".*\.\(h\|cpp\)"
# ^^^^^^^^^^^^^^^^^^^^^^^
Then, it is just a matter of executing grep
on each of its results:
find -type f -regex ".*\.\(h\|cpp\)" -exec grep "your pattern" {} +
If you don't have this distribution of find you have to use an approach like Amir Afghani's, using -o
to concatenate options (the name is either ending with .h
or with .cpp
):
find -type f \( -name '*.h' -o -name '*.cpp' \) -exec grep "your pattern" {} +
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
And if you really want to use grep
, follow the syntax indicated to --include
:
grep "your pattern" -r --include=*.{cpp,h}
# ^^^^^^^^^^^^^^^^^^^
Solution 7 - Grep
This answer is good:
grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP email@domain.com
But it can be updated to:
grep -r -i --include \*.{h,cpp} CP_Image ~/path[12345] | mailx -s GREP email@domain.com
Which can be simpler.
Solution 8 - Grep
The easiest way is:
find . -type f -name '*.extension' 2>/dev/null | xargs grep -i string
Add 2>/dev/null
to kill the error output.
To include more file extensions and grep for password throughout the system:
find / -type f \( -name '*.conf' -o -name "*.log" -o -name "*.bak" \) 2>/dev/null |
xargs grep -i password
Solution 9 - Grep
ag
(the silver searcher) has pretty simple syntax for this
-G --file-search-regex PATTERN
Only search files whose names match PATTERN.
so
ag -G *.h -G *.cpp CP_Image <path>
Solution 10 - Grep
You should write "-exec grep " for each "-o -name ":
find . -name '*.h' -exec grep -Hn "CP_Image" {} \; -o -name '*.cpp' -exec grep -Hn "CP_Image" {} \;
Or group them by ( )
find . \( -name '*.h' -o -name '*.cpp' \) -exec grep -Hn "CP_Image" {} \;
Option '-Hn' shows the file name and line.
Solution 11 - Grep
Here is a method I normally use to find .c and .h files:
tree -if | grep \\.[ch]\\b | xargs -n 1 grep -H "#include"
Or if you need the line number as well:
tree -if | grep \\.[ch]\\b | xargs -n 1 grep -nH "#include"
Solution 12 - Grep
If you want to filter out extensions from the output of another command e.g. "git":
files=$(git diff --name-only --diff-filter=d origin/master... | grep -E '\.cpp$|\.h$')
for file in $files; do
echo "$file"
done