FInd all string occurences

Hi Folks -

I have a need to find a string occurrences in a list of *.txt files.

My code is as follows:

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

I was wondering a few things.

  1. Is that an acceptable method to achieve my goal?
    A. It works as expected but just curious
  2. Is there a way to output the total # of found occurrences with a file name, then total everything up into 1 value?

Thank you all!

Why run cat when you can run grep?

This will list counts from all files:

find . -name '*txt' -exec grep -icH " 0" '{}' '+'

This will add a TOTAL line to the end:

find . -name '*txt' -exec grep -icH " 0" '{}' '+' | awk -F: '{ T += $2 } 1; END { print "TOTAL:" T }'

Same thing, but excludes files with zero matches:

find . -name '*txt' -exec grep -icH " 0" '{}' '+' | awk -F: '{ T += $2 } $2+0; END { print "TOTAL:" T }'

grep -H forces grep to always print the related filename.

1 Like

Coronaa -

Thank you so much! I will test now.

If I wanted to spool the results to a text file instead of print to screen, would I just simply do this:

find . -name '*txt' -exec grep -icH " 0" '{}' '+' | awk -F: '{ T += $2 } 1; END { echo "TOTAL:" T  >>results.txt }'

Thank you!

No. There is no awk echo command. Try:

find . -name '*txt' -exec grep -icH " 0" '{}' '+' | awk -F: '{ T += $2 } 1; END { print "TOTAL:" T }' > results.txt

if you want to replace the contents of results.txt with the output from this run, or:

find . -name '*txt' -exec grep -icH " 0" '{}' '+' | awk -F: '{ T += $2 } 1; END { print "TOTAL:" T }' >> results.txt

if you want to append the output from this run to that file's previous contents.

1 Like

Folks -

Thank you very much! It's working as expected!!

Hi Guys -

I have one more request. I need to exclude or ignore a search string from my search.

The string is as follows:

I need to add it to the following code:

find . -name '*txt' -exec grep -icH " 0 " '{}' '+' | awk -F: '{ T += $2 } 1; END { print "TOTAL:" T }' >>TCP_FinSAP_20161203.txt

Thank you!

Needs a slightly different approach - use awk in the first place instead of grep | awk :

find . -name "*.txt" -exec awk '{n=gsub (/ 0/, "&"); m=gsub (/"AC_STAT" 0/, "&"); CNT[FILENAME]+=n-m; TOT+=n-m} END {for (c in CNT) print c, CNT[c]; print "Total", TOT}' {} +

The -exec awk can be run several times; then the "Total" does not work as intended.
So the pipe must be there...

1 Like

Thanks for pointing that out. Try

find . -name "*.txt" -exec awk '{CNT[FILENAME]+= gsub (/ 0/, "&") - gsub (/"AC_STAT 0/, "&")} END {for (c in CNT) print c, CNT[c]}' {} + | awk '{TOT += $2} 1; END { print "Total", TOT}'

Thank you, RUdi!

Which portion is my original search string though?

This portion?

(/ 0/

Yes. You can also use " 0" .

Thank you!

So:

find . -name "*.txt" -exec awk '{CNT[FILENAME]+= gsub (/" 0"/, "&") - gsub (/"AC_STAT 0/, "&")} END {for (c in CNT) print c, CNT[c]}' {} + | awk '{TOT += $2} 1; END { print "Total", TOT}'

Or is it:

find . -name "*.txt" -exec awk '{CNT[FILENAME]+= gsub (" 0", "&") - gsub (/"AC_STAT 0/, "&")} END {for (c in CNT) print c, CNT[c]}' {} + | awk '{TOT += $2} 1; END { print "Total", TOT}'

The second option. For the future: how about doing some tests and finding out by yourself?

If your grep supports the P flag for Perl comparability regex then you can just make this little adjustment:

find . -name '*txt' -exec grep -PicH '(?<!"AC_STAT") 0 ' '{}' '+' | awk -F: '{ T += $2 } 1; END { print "TOTAL:" T }