How to find the total number of occurrences of text and files with find command

37,628

Solution 1

For question 1, you can do this:

find . -name "*.txt" | xargs grep -i "abc" | wc -l

This counts the total number of matches for abc in all text files.

And for question 2, I came up with:

find . -name "*.txt" -exec grep -i "abc" {} + | cut -d: -f1 | sort | uniq | wc -l

This gets just the unique filenames from the list of matches and counts them (the sort is probably not needed).


As pointed out by miracle173, grep comes with a "one match per file" flag so the command can be shortened to just:

find . -name "*.txt" -exec grep -il "abc" {} + | wc -l

Solution 2

grep's -c option is what you need here

find . -name \*txt | xargs grep -c -i "abc" | {
    total=0
    count=0 
    while IFS=: read name num; do 
        ((num > 0)) && ((count+=1))
        ((total+=num))
    done
    echo total=$total 
    echo count=$count
}

The braces to group the commands around the while loop are required to keep the variables in one scope for that subshell.

Solution 3

Number of abc's contained in files:

To count the number of all "abc"'s in the .txt files, use grep -c and find and - exceptionally - cat:

find . -name "*.txt" -exec cat {} + | grep -ic abc

Grep -c will do the total count for you - something I didn't find in SigueSigueBen's answer, which contains unjustified calls to xargs, imho. The other 2 answers where to long for me. I didn't study them and wouldn't write such things myself.

Number of files containing abc:

find . -name "*.txt" -exec grep -iq abc {} ";" -printf "1" | wc -c 

This will not fail with filenames (which are rarely, I admit) containing newlines in their name (which is perfectly legal).

Share:
37,628

Related videos on Youtube

amitsharma
Author by

amitsharma

Updated on September 18, 2022

Comments

  • amitsharma
    amitsharma almost 2 years

    I am trying to run the find command to find the total number of occurrences of a particular text string and also the number of files which has this text string.

    What I have right now is this command.

    find . -name "*.txt" | xargs grep -i "abc"

    This reports all the "*.txt" files which contain the text "abc". I want either one or two find command to get

    1. Total number of times abc appears
    2. Total number of files which has abc in it.
  • miracle173
    miracle173 about 12 years
    2. is a little bit complicated. grep -l will display one line for each file containing the search string.
  • amitsharma
    amitsharma about 12 years
    @SigueSigueBen Thanks for your answer. The first one works but for the second one looks like you are missing something after wc -. I am getting this error wc: cannot open - find: bad option out
  • Ayaz Ali Khatri
    Ayaz Ali Khatri about 12 years
    @Nomad There was a missing character at the end.
  • Ayaz Ali Khatri
    Ayaz Ali Khatri about 12 years
    @miracle173 I'm not surprised there's a shorter answer. I didn't know about grep -l to be honest. I've updated my answer.
  • amitsharma
    amitsharma about 12 years
    Guys thanks to everyone, who contributed to this question, for your time and help. I will tryout the suggestions and will come back here with update.
  • miracle173
    miracle173 about 12 years
    countcontains the number of files found by find . -name \*txt and not the number files containing the string because grep -c returng 0 if the string is not found in a file.
  • Angel Todorov
    Angel Todorov about 12 years
    @miracle173, quite right. answer updated.
  • amitsharma
    amitsharma about 12 years
    @SigueSigueBen, so which command is which now. Looks like find . -name ".txt" -exec grep -il "abc" {} + | wc -l brings the number of occurrence and find . -name ".txt" | xargs grep -i "abc" | wc -l brings number of files. Can you please explain or update your answer with more clarification. Thanks
  • amitsharma
    amitsharma about 12 years
    @glenn jackman, your solution is very elegant and one stop approach. I like it. Plus it works :).
  • Ayaz Ali Khatri
    Ayaz Ali Khatri about 12 years
    It should be as per my original answer.
  • amitsharma
    amitsharma almost 12 years
    @glenn jackman, your solution is great but for sometimes i was getting error for it, otherwise i would have accepted your answer. But thank you so much for your help and answer, really appreciate it.
  • Angel Todorov
    Angel Todorov almost 12 years
    @Nomad, what errors?