How can I find out how many files ending in .c or .cpp inside a directory contain the string: string?
Matthew Barrera
How can I find out how many files ending in .c or .cpp inside a directory contain the string: string?
The string can occur anywhere in the entire file, including comments or as part of a larger string.
6 Answers
If you know that your filenames cannot contain newlines, then
grep -rFl --include='*.c' --include='*.cpp' string . | wc -lOtherwise
find . -type f \( -name '*.c' -o -name '*.cpp' \) -exec grep -Fq string {} \; -printf x | wc -c 1 grep -l string *.c *.cpp | wc -l- If any filenames contain newlines, the count will be too high.
- If the globs fail to match, you will get an error like
grep: *.c: No such file or directory, but the count will still be correct.
This is like a quick and dirty version of steeldriver's answer.
2Use the grep command to find out:
find /path/to/directory -type f \( -name "*.c" -o -name "*.cpp" \) -exec grep "string" {} \; | wc -l 0 Simple way would be via bash recursive glob combined with single match parameter in grep (one file - one match) :
shopt -s globstar
grep -m 1 'string' */**.{c,cpp} | wc -lWhy not grep -R ? Because -R walks through all files, and doesn't filter .c or .cpp files, so we use bash's globbing to do that job.
Otherwise, for shell-agnostic way you can use find:
find -type f \( -iname "*.c" -or -iname "*.cpp" \) -exec grep -q 'string' {} \; -and -print | wc -l I would recommend using the tool ripgrep (snap) for these kinds of task (grepping in source code repositories):
$ rg -g '*.c' -g '*.cpp' -l string | wc -lThe following command may also be useful:
$ rg -t c -t cpp -l string | wc -lWhich searches files with the following extensions:
$ rg --type-list | grep -E '^c:|^cpp:'
c: *.H, *.c, *.h
cpp: *.C, *.H, *.cc, *.cpp, *.cxx, *.h, *.hh, *.hpp, *.hxx, *.inlThe flags used are:
-l, --files-with-matches Only print the paths with at least one match. This overrides --files-without-match. -g, --glob <GLOB>... Include or exclude files and directories for searching that match the given glob. This always overrides any other ignore logic. Multiple glob flags may be used. Globbing rules match .gitignore globs. Precede a glob with a ! to exclude it. -t, --type <TYPE>... Only search files matching TYPE. Multiple type flags may be provided. Use the --type-list flag to list all available types. You should be able to find out how many files end in .c or .cpp that contains the word "string" by executing:
cat *.c* | grep -i "string" | wc -l