7

I am supposed to find and display the count of the number of files that contain the word carrot (case ignored)

So far this is what I have, I am just not sure how to add the wc into it to count how many files there are that have the word carrot

find . -exec grep -i carrot {} \;

  • How would I do it using the find command? Sorry for not specifying. – John Oct 12 '13 at 23:08
  • 1
    Why do you want to use find? grep -r is recursive. – Marco Oct 12 '13 at 23:10
13

First of all, as others have said, there is no reason to use find, just use recursive grep:

grep -irm 1 carrot . | wc -l 

The -m 1 ensures that grep will stop searching each file after the first match. Without it, you are not counting the number of files that contain carrot but the number of lines, the same file will be counted multiple times if it contains multiple instances of carrot. From man grep:

    -r, --recursive
          Read all files  under  each  directory,  recursively,  following
          symbolic  links  only  if they are on the command line.  This is
          equivalent to the -d recurse option.
   -i, --ignore-case
          Ignore  case  distinctions  in  both  the  PATTERN and the input
          files.  (-i is specified by POSIX.)
   -m NUM, --max-count=NUM
          Stop reading a file after NUM matching lines. 

If you really, really want to do it with find, you could do

find . -type f -exec grep -im 1 carrot {} \; | wc -l

Note that I am specifying -type f since you don't want to grep directories.

  • 1
    This isn't correct. Providing -m 1 will stop after one match, not one match per file. So this will actually always return 1. I think the second solution does it correctly though. – Phonon Nov 11 '15 at 18:13
  • @Phonon no it won't, try it. At least on my Linux system, it finds the first match in each file. grep -r still deals with individual files, it doesn't just cat all of them. – terdon Nov 11 '15 at 18:32
4

Find the number of files contain the word carrot

number_of_files=`grep -l -r -i "carrot" . | wc -l`

Meaning for the grep arguments:

-l, --files-with-matches
         Only the names of files containing selected lines are written to standard output.  grep will only search a file until a match has been found, making
         searches potentially less expensive.  Pathnames are listed once per file searched.  If the standard input is searched, the string ``(standard
         input)'' is written.

-R, -r, --recursive
         Recursively search subdirectories listed.

-i : case insenstive

wc -l : prints out the number of lines passed as input to the program. In our case, these lines are the names of files with matching input pattern found by grep.

Print the output

echo $number_of_files
  • 1
    @Downvoter care to comment the reason ? – smRaj Oct 12 '13 at 23:28
  • I did not downvote but this does not count the number of files that contain a string, it counts the number of lines that contain it. If a file has three lines that match the pattern you are searching for, it will be counted three times. Also, you don't need the wc since grep has the -c option. Add -c and -m 1 to avoid duplicate matches. – terdon Oct 12 '13 at 23:33
  • @terdon: I do not have enough reputation to comment on your answer. So, I am putting it here, OP needs the total number of files that contain the word "carrot". Your grep -ircm 1 carrot . doesn't give the number of files that contain a string. Instead, -c option provides the number of matches for the searched pattern it found per file basis . Example; filename1:count filename2:count . I am unsure your answer is going to be useful for the purpose requested by OP – smRaj Oct 13 '13 at 0:02
  • @terdon: Additionally with grep -ircm 1 carrot ., grep prints out file names even if it doesn't contain carrot with zero as count like : file_name1:0 file_name2:0 – smRaj Oct 13 '13 at 0:06
  • You're quite right, serves me right for posting too quickly, thanks. -l is better than -m as well but hey, I'll stick with my way since you're already using it :) – terdon Oct 13 '13 at 0:09
3

A variant of smRaj's solution would be a double invocation of grep. The following would give the same result as grep [etc] | wc -l:

grep -l -r -i "carrot" . | grep -c .

The following would print a numbered list of the files containing the searched word.

grep -l -r -i "carrot" . | grep -n .
  • +1 I was going to answer the exact some thing when I saw that you already have :) – Joseph R. Oct 13 '13 at 10:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.