Iterating Over a Series of Five Line Text Records and Activating a Different Action for Each Line of The Record


I have a document with a list of entries will always be grouped in the same ordering and same number of lines. Each entry is separated by an empty line.

I am starting by copying the contents of the document into the System Clipboard. From there I tried to do For Each Item in a Collection -> Lines in System Clipboard, but this only lets me perform the same action on every line. I want to perform a different action based on what line number it is on, each unique item has 5 lines. Line 1 needs a different action than Line 2.

Text Field
Description Field

Text Field
Description Field

I am trying to use KB Maestro to loop over this document, in lines of 5, and also perform a repeatable series of action for the corresponding line.

Example - This file has 2 entries, one for Google, and one for Apple, each one is 5 lines, and the empty line is the separator. For each entry I want to:

For simplicity sake say I only have two different actions, one move the mouse and do something, and the rest are paste. How can I make it differentiate the action based on what line number of the loop it is on?

For loop --
Line 1 - Move mouse select on calendar - 01/01/2023
Line 2 - Paste in text box -
Line 3 - Paste in text box- Google
Line 4 - Paste in text box- Text Field
Line 5 - Paste in text box- Description Field
-- Reach the end of item 1

Repeat the same for the next item.

Hey Sean,

I've gone for the simplest possible solution here:

  • Trim the copied text to remove leading and trailing vertical whitespace.
  • Iterate through the lines with a counter.
  • Use a Switch-action to operate on the given line number
  • Reset the counter on line 6.


Interate Through Text Records of Five Lines v1.00.kmmacros (13 KB)

Macro Image

Brilliant. Switch/Case is what I was looking for!

Thanks !!

While you could consider this as a loop-in-a-loop:

for each 6 line chunk
   for each line in current chunk
      do something

...if you take a step back you can instead look at the "inner loop" as a fixed sequence of 5 distinct actions (assuming your fields are always in the same order).

KM can treat any text block as a pseudo-array, and you can define a custom delimiter. Unfortunately you can't use a return/newline, so you have to search'n'replace those with a delimiter you can use.

So, as an alternative to @ccstone's method:

Looping Through Chunks.kmmacros (11.2 KB)


Starting with Local__i set to 0 may seem a bit odd, but i find it much easier when debugging if line 1 ops are "index + 1", line 2 ops are "index + 2", etc.

1 Like

Hey Nige,

I thought about doing something like that, but it was too much bother... :sunglasses:

Thanks for going to the trouble.

I'm not opposed to using Keyboard Maestro native actions to do loops within loops, but I visualize written code better.

This is a pretty simple task for AppleScript – so just for fun here's one more option.

# Auth: Christopher Stone <>
# dCre: 2023/01/12 07:05
# dMod: 2023/01/12 07:05 
# Appl: Keyboard Maestro
# Task: Process Text Records Line by Line.
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @Keyboard_Maestro_Engine, @Process, @Text, @Records
property LF : linefeed

# Test data.
set clipboardData to "

Text Field
Description Field

Text Field
Description Field


# Use text on the Clipboard.
# set clipboardData to the clipboard 

# Strip any extra vertical whitespace.
set clipboardData to its kmCng:"\\A\\s+|\\s+\\Z" inStr:clipboardData withStr:"" usingRegEx:true usingCase:false usingTokens:false

# Split the records into a list.
set {oldTIDS, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {LF & LF}}
set clipboardData to text items of clipboardData
set AppleScript's text item delimiters to oldTIDS

set lineCounter to 0

# Process the records.
repeat with theRecord in clipboardData
   # Process the lines in the records.
   repeat with theLine in (paragraphs of theRecord)
      set lineCounter to lineCounter + 1
      if lineCounter = 1 then
         set theSubmacro to 1
         # Do something with (contents of theLine)
      else if lineCounter = 2 then
         set theSubmacro to 2
         # Do something with (contents of theLine)		
      else if lineCounter = 3 then
         set theSubmacro to 3
         # Do something with (contents of theLine)
      else if lineCounter = 4 then
         set theSubmacro to 4
         # Do something with (contents of theLine)
      else if lineCounter = 5 then
         set theSubmacro to 5
         # Do something with (contents of theLine)
      end if
   end repeat
end repeat

on kmCng:regExPat inStr:dataStr withStr:replacePat usingRegEx:regExBool usingCase:caseBool usingTokens:tokensBool
   tell application "Keyboard Maestro Engine"
      set foundDataList to search dataStr for regExPat replace replacePat ¬
         regex regExBool case sensitive caseBool process tokens tokensBool
   end tell
end kmCng:inStr:withStr:usingRegEx:usingCase:usingTokens:

Depending upon what you're doing you might be able to use pure AppleScript, or you might need to call out to subMacros in KM.


1 Like

I'm still very much in the "playing with KM" stage, so for me it was "learning" rather than "trouble" :wink:

One day I might actually have some macros that I use...

IMO, unless something is objectively wrong, personal preference trumps most everything. It's a lot easier to create/debug/maintain any system (not just code or macros) when "fits" you.

Of course, there's also much to be said for stepping out of your comfort zone and trying different methods -- which is why I enjoy dissecting the solutions you and the other KM gurus (you know who you are...) post here!

1 Like