26

How can I count the number of files (in a directory) containing a given string as input in bash/sh?

5 Answers 5

42

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.

3
  • 1
    This 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?
    – user16142
    Mar 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.
    – Agargara
    Oct 17, 2017 at 0:09
  • I have to use grep -l "string" * |& wc -l
    – bebbo
    Feb 27, 2022 at 14:31
9

greps parameter -l will only output the filenames which are matching $PATTERN, wc can count them afterwards.

grep -l "$PATTERN" * | wc -l
2
  • thanks, but was wondering with a pattern in the file ... sorry for the ambiguous question
    – user4311
    Jan 29, 2011 at 21:03
  • If so, take Wolf's answer.
    – wag
    Jan 29, 2011 at 21:04
3
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.

8
  • But something is missing? because it does not work
    – user4311
    Jan 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)
    – user4311
    Jan 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
3

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).

0
grep -Rl "string" pathtofolder/ | wc -l

this worked for me and returned number of occurrences of the "string" in specified directory.

You must log in to answer this question.