How to count the number of occurrences of a string in more than one file?

I am trying to achieve this:

  • Copy some text string to the system clipboard
  • Trigger a macro that would count the number of occurrences of this string in two specific .txt files
  • If count =0, it would notify me message A, if count >1, it would notify me message B, if count greater or equal to 2, it would notify me message C.

My problem is I can't find a proper way to count the number of occurrences in more that one files.

Tried reading KM wiki, posts, even A.I.services. With no luck. So, I am soliciting real intelligence :grinning:

Edit: Big thank you to whoever took the time to share a solution! The one that works for me is @ComplexPoint 's one. But feel free to try all of them!

The command "grep -c mystring" will count how many occurrences of mystring are in the standard input. The command "grep -c mystring file file2" should give you the counts in each file. Using a little more text processing, those two results can be added together to get your result. Is that enough to get you started?

The command "cat file1 file2 | grep -c mystring" should get you what you want. Just make sure you use the full pathnames for the files.

Here is the code you probably want: (however your words were to do nothing if the value=1, so that's what my code does. You probably misspoke.)

1 Like

There are other simple ways of doing this.

This is not one of them. :joy:

Here is a macro that uses KM Engine's "count found in" AppleScript command.
How to count the number of occurrences of a string in more than one file.kmmacros (6.9 KB)

Macro Image

KM Engine provides a number of easily overlooked AppleScript search text commands with many of the usual regex/non-regex options:

count found in
found in
search

Here is the script in the macro:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
property author : "@CRLF"

--Import KM variables HERE:
set kminstance to system attribute "KMINSTANCE"
tell application id "com.stairways.keyboardmaestro.engine"
	set path1 to getvariable "localFilePath1" instance kminstance
	set path2 to getvariable "localFilePath2" instance kminstance
	set theSearchString to getvariable "localSearchString" instance kminstance
end tell

--This block is for debugging in Script Editor. It does nothing when run in Execute an AppleScript action
if name of current application is not "osascript" then
	set path1 to "test document1.txt"
	set path2 to "test document2.txt"
	set theSearchString to ¬
		"your search string"
end if

set contents1 to contentsOfFileAtPath(path1)
set Contents2 to contentsOfFileAtPath(path2)

--The Definition of "count found in" from KM Engine's Scripting Dictionary
(*
count found in
count found in (verb)Search a string for a string, returning the number of matches (from Keyboard Maestro Engine Suite)
FUNCTION SYNTAX
set theResult to count found in text ¬
     for text ¬
     regex boolean ¬
     case sensitive boolean ¬
     process tokens boolean
RESULT
integerthe number of matches.
*)


set {count1, count2} to {0, 0}
tell application id "com.stairways.keyboardmaestro.engine"
	set count1 to count found in contents1 ¬
		for theSearchString without regex
	set count2 to count found in Contents2 ¬
		for theSearchString without regex
end tell

--OUTPUT THE SUM
return count1 + count2

on contentsOfFileAtPath(thePath)
	set {theContents, theError} to current application's NSString's stringWithContentsOfFile:thePath usedEncoding:(current application's NSUTF8StringEncoding) |error|:(reference)
	if theError is not missing value then error theError's localizedDescription as text
	return theContents as text
end contentsOfFileAtPath

To debug just paste it into Script Editor and change the variables in the debug block

@Airy Thank you! I modified the shell script a little bit to this:

cat file_1 file_2 | grep -c "$(pbpaste)"

While every time I try the script in iTerm with my three hypotheses (no, one, two occurrences) everything is fine, I get weird results when I use the same script in Keyboard Maestro.

With no occurrence, I get an error Task failed. Macro cancelled...
With one occurrence, I get no notification.
With two occurrences, I get notified a message telling me the string was written one time.

Tried to run the script alone in Keyboard Maestro. The value of VarName changes with one or two occurrences. Not when there is no occurence.

Weird. Isn't it?

And another variant:

Keyboard Maestro .countFoundIn for given term- summed over a list of files.kmmacros (7.0 KB)

2 Likes

Variants +1

A KM non-scripting way modified slightly from the wiki example on this page:

Regular Expressions [Keyboard Maestro Wiki]

1 Like

Not weird at all. That's what you told me to do. I advised you that you probably misspoke and you probably meant "=1". So just change that in my Switch action.

@ComplexPoint Thank you!

I tried your script after adapting the file paths. Got the following errors: one about read file. The other about the JavaScript for automation script. I unfortunately can't say more these two errors.

You are using a current version of Keyboard Maestro ?

Might there be a problem with the file paths ?


(Would really need to see the error messages, and file paths, to comment properly)

@ComplexPoint I made it work!

The problem was apparently I forgot to replace "currency" with %SystemClipboard% in the first action.

Thank you for your time! Hope it will continue to work as smoothly as it is now :grinning:

1 Like

I've made a couple of small edits above

  1. local_Term now bound, as you suggest, to the value of %SystemClipboard%
  2. a minor adjustment to the JavaScript code to prevent an error if no textual value is bound to local_Term

For fun, here's the no-scripting-required "easy mode" version. All it does is "For Each" for a substring matching the System Clipboard contents "For Each" file in a list, adding 1 to a counter for each match:

Count Occurences.kmmacros (9.0 KB)

1 Like