For Each - Possible to Isolate Matches?

I feel like this is one of those things that will be so self-evident once it's pointed out that I'll facepalm my forehead through my brain, but...

Let's say I have an If Then Else action within a For Each, to see if each line of one variable matches another variable; for example, trying to see if any of the files in a folder matches the name of one stored on the clipboard. If one of the lines matches, I want to open that file and then set Variable TRUE, but if not, I want to set Variable FALSE.

Here's what I'm trying to get my head around. Unless I've misunderstood how For Each actions work, I think they perform the same action on each line, including setting the appropriate variable. So, even if one matching line sets Variable TRUE, the other lines that don't match will set Variable FALSE. At least it looks like that's what's happening from watching steps in the Debugger.

Is there a way to look for a match against each line and only perform an action for the line that matches?

For Each line will get from the string line by line.
You probably need to post a sample macro for others to see what's wrong with your macro.

The If Then action checks if your SystemClipboard "contains" the line.

Unless there might be multiple matches, you may add within the If Then action: if matches, then do something, and cancel the macro.

Hey Neil,

So you've got an arrangement similar to this?



Files on Disk:


Is there any chance the name on the clipboard will match more than one file name?


Thanks for the replies guys.

Here's what I'm dealing with:

There's no chance the checked variable could match more than one file in the folder, as the files it contains are specifically made to match one name. The Cancel Profile Macro part was an experiment to see if making the following part of the macro dependent on a variable might be more effective than either cancelling it or not. It hasn't made any difference. Might as well have "Cancel This Macro otherwise nothing" in its place. Loops subesquent or previous to the one that matches are still getting through.

Is that enough to go on?

Hi @noisneil,

Add this action after the "Set Variable ... to 'Yes'" action.
You need to immediately break from the loop. Otherwise, the loop will continue if the "Yes" one is not the last, and you will eventually get a "NO" for the variable.


1 Like

Ahhh. I've seen this "break from loop" thing hanging around. Makes sense now that you explain it.

Only thing is, if there are non-matches before the match, it won't stop them, right?

Right, because if the condition does not meet, it will go to the "ELSE/otherwise" section.


Just add one more thing.
The "break from loop" action is fitting for you because it is expected to have either 0 or 1 match.

If there is possibility of multiple matches, you will want every item in your list is checked, then you can use revise your macro to something like this:

set variable count to 0
if condition meets
  then do A, B, C
  set count to count + 1
  do nothing

# in the following, use another if ... then ... statement
if count = 0
  then do D, E, F # it means there is no match previously.
else  # i.e., count > 0 ā†’ there are matches previously.
  then do H, I, J

# using the "count" variable, you can get the number of matches, 
# although the number of matches may not be needed.

Hmmm. I'll have to think laterally, won't I. Cheers for the info. :+1:t3:

Ok I don't think I do understand Break From Loop. It breaks my whitelist.

Without it, the macro works properly, but shows false in both categories; with it, the macro doesn't work. My head hurts.

For context: This macro performs an automatic OCR scan of the current plugin window in Logic, if the current front window is not one of Logic's main interface windows (defined by a Logic Window Whitelist). Next, if the OCR'd plugin name matches my Plugin Whitelist, it attempts to find a blank applet in a specific folder that matches that plugin name. If one exists, it opens the applet, which in turn triggers a plugin-specific profile on my Stream Deck. If none exists, it opens a generic plugin profile with common controls. If the plugin name wasn't found on the plugin whitelist, it loads my main Logic profile.

Here's the macro group in case anyone wants to check it out.

Logic Stream Deck Profiles.kmmacros (304.1 KB)

Put it after, not before, the actions inside the if then section, like this:


When it breaks from the loop, nothing inside the if then else block will be executed.
In other words, if you put the break from loop before the "set variable" action, the "set variable" action will not be executed.

:man_facepalming:t2:I knew a facepalm moment was nigh. Of course! Thanks for clarifying that.

I suppose this might be off-topic, but I'm not sure why I'm seeing a match here:

1 Like

I think the problem lies with the value of %variable%pluginName% ? why is it "| soothe2 |" and not "soothe2".
the "|" character has a special meaning in regex. it stands for "or". Like "one|two" matches "one" or "two"

if the plugin really has this character is its name you have to escape it like this:
\| soothe2 \|
and it will match the "| soothe2 |" exact string (with the spaces included...).

and if you ever need again to understand what happens with a regex match you can go to


Genius! I've added a search and replace for | to remove it from the PluginName variable. Thankyou!

For anyone who's interested in what this macro does, here's a video that explains it:

Here's a post I made on it:

I've worked on it a bit since that post but I want to tie up some loose ends before updating it.

@ccstone wisely pointed out that it would be helpful to upload a test version of this. Not everyone has Logic Pro and a Stream Deck, but here it is all the same. Included are:

  • The main macro group
  • A macro group that cleans the variables when Logic deactivates. This is necessary as the main macro is programmed not to reload the Logic Profile when switching between the main interface windows. As a result, switching to another app and back would mean the Logic profile wouldn't load, so the variables have to be deleted when that happens.
  • A folder of blank trigger apps that need to be associated with the included Stream Deck profiles in the Stream Deck software.
  • Some basic Stream Deck profiles for testing.
  • A logic session with three open plugin windows. For the purposes of this test, Channel EQ should trigger a specific profile, Compressor should trigger a generic profile and Chorus should trigger the Logic profile (if it's not already active). For some reason, although it does switch to the correct profile initially, this test version switches back to the Logic profile every time. I've gone through it step-by-step and can't figure out why. My main version of this doesn't have this problem and only goes squiffy when there's a heavy session that's taxing the CPU a bit. There must be some kind of jankiness in my macro that's exposed during heavy sessions, which is why I'm still trying to refine it.

Profile (1.6 MB)