How can I count the number of files (in a directory) containing a given string as input in bash/sh?
5 Answers
grep -l "string" * | wc -l
will search for "string" in the contents of all files in the working directory and tell you how many matched.
-
1This won't work if there are a lot of files in the directory, it will throw the error "zsh: argument list too long: grep". Any ideas on how to get rid of this?– user16142Mar 2, 2012 at 6:17
-
3@user16142 grep the directory instead of the files:
grep -lr "string" directory | wc -l
If you don't want recursive search, you can use find with maxdepth option:find directory -maxdepth 1 -type f -exec grep -l "string" {} + | wc -l
Note that this second option is slower than grep.– AgargaraOct 17, 2017 at 0:09 -
grep
s parameter -l
will only output the filenames which are matching $PATTERN
, wc
can count them afterwards.
grep -l "$PATTERN" * | wc -l
-
thanks, but was wondering with a pattern in the file ... sorry for the ambiguous question– user4311Jan 29, 2011 at 21:03
-
awk '/pattern_to_look_for/ {s+=1; nextfile;} END {print s}' *
Clarification: This looks for the number of files that has the "pattern_to_look_for" in their contents and not in their filenames (like Wag's answer). From your question it's hard to tell what you are looking for.
-
But something is missing? because it does not work– user4311Jan 29, 2011 at 21:01
-
If you look for the string duck you must write it like /duck/ in Awk. Are you doing that? Jan 29, 2011 at 21:05
-
yes, the output: awk: read error (Is a directory)– user4311Jan 29, 2011 at 21:07
-
Wolf's answer will give you duplicates. If there are several occurances of the string you are looking for in one of the files, it will count as extra matches. Jan 29, 2011 at 21:08
-
Well, if you have directories in the folder you have to do some extra stuff like replacing the star with something like this
find . ! -name . -prune -type f
(don't miss the backticks). This command only lists the files in the folder. Jan 29, 2011 at 21:11
This works in most shells including Bash with any filename, provided you have access to the GNU implementation of grep
or compatible:
grep -lZe "$pattern" -- * | tr -cd '\0' | wc -c
Explanation:
grep
's-Z
option prints every result with a ␀-byte separator. This character can't be part of a file name, so we can simply count the number of separators to get the number of files.- To get rid of the other characters in the output, we simply remove everything except the ␀ bytes using
tr
. - Then just count the characters with
wc
.
With any grep
implementation, you can also do:
grep -le "$pattern" ./* | LC_ALL=C grep -c /
Here counting the lines with a /
.
The equivalent with recursive grep
would be:
grep -rle "$pattern" .//. | grep -c //
Though that requires support for the non-standard -r
option, or standardly:
find .//. -type f -exec grep -le "$pattern" /dev/null {} + | LC_ALL=C grep -c //
(bearing in mind that file paths may end up being longer than the maximum line length supported by your grep
though).
grep -Rl "string" pathtofolder/ | wc -l
this worked for me and returned number of occurrences of the "string" in specified directory.