Reverse Line Order in text


I was wondering if there is a way to reverse lines from text. Something similar like this tool online:

I've found these topics on the forum for reversing words or characters, but couldn't re-engineer that to what I was hoping to build.

Someone here willing to help me with this problem? :slight_smile: Thanks!

1 Like

Reverse Lines Macro (v9.0.2)

Reverse Lines.kmmacros (5.4 KB)

This could surely be made to be more efficient logically, but here's one way. This is designed to work on lines that have been copied to the system clipboard before running the macro.

Haha, thx! I'm always amazed at some of your solutions. It works in my first testing :D,

That's a long macro. Why not use a shorter one, like this:


There are many ways to solve this. I didn't validate if this method handles special cases like trailing spaces. If this doesn't work tell me what's wrong with it and I'm sure I can fix it.


While KM does not directly provide a simple solution, this is easily done in JXA, using a Execute a JavaScript For Automation action.

Assuming your source text is in a KM Variable "Local__SourceStr", this script will do the job:


Example Output


MACRO:   Reverse Lines [Example]

~~~ VER: 1.0    2019-09-25 ~~~
Requires: KM 8.2.4+   macOS 10.11 (El Capitan)+
(Macro was written & tested using KM 9.0+ on macOS 10.14.5 (Mojave))

DOWNLOAD Macro File:

Reverse Lines [Example].kmmacros
Note: This Macro was uploaded in a DISABLED state. You must enable before it can be triggered.

JXA Script

(function myMain() {    // ~~~ automatically executed when this script is executed ~~~

var ptyScriptName   = "Reverse Lines in String"
var ptyScriptVer     = "1.0"
var ptyScriptDate   = "2019-09-25"
var ptyScriptAuthor = "JMichaelTX"

// --- SET CURRENT APP VARIABLE NEEDED FOR DIALOGS & StandardAdditions.osax ---
var app = Application.currentApplication()
app.includeStandardAdditions = true

// --- KM ENGINE APP ---
var kmInst = app.systemAttribute("KMINSTANCE");  // needed for Local & Instance variables
var kmeApp = Application("Keyboard Maestro Engine")

var sourceStr = kmeApp.getvariable("Local__SourceStr",  {instance: kmInst});
if (!sourceStr) {throw new Error('Source string MUST contain at least one line'); }

var sourceList = sourceStr.split('\n');
var revList = sourceList.reverse();
return revList.join('\n');

})();  // ~~~ function myMain() is automatically executed when this script is executed ~~~

My goodness you guys have some pretty great answers.. I got into KM from a visual designer perspective, 'ohhh look at this feature 'click on found image'.. nice!!' 99% of my solutions. I'm learning a ton from you guys and the forum! Thx! Will try them all.

Why use three commands when you can use one ;-?

(When it comes to processing text, bailing out to a shell script will almost always be “easier” because Unix has so many tools for text manipulation. But I put “easier” in quotes because you have to find the right incantation, which can tricky, but often not much harder than figuring out how to do it in Keyboard Maestro natively.)


Good one. Beautiful. I'll be honest: half the time when I answer a question I don't know the answer until I google it. And I don't always find the best answer when I do that, as you have shown in this case.

However I can make your solution 56.25% shorter, just drop the "/usr/bin/".

7 posts were split to a new topic: Using Shell Scripts with KM

Appreciate the discussion everyone! In my testing, the output for the three command script cat -n | sort -rn | cut -f2- provided by Sleepy yielded perfect results whereas the single command provided by tjluoma misses a line break near the beginning of output. Screenshots of testing output below.

I replied to tjluoma's thread post that Sleepy's command worked for me whereas tjluoma's had a missed a line break near the beginning of output.

That's because the last line of both your text samples don't terminate with a linebreak.

And I don't know if this is a recent addition to KM, but to do this "natively":

@JeremyBrown @Nige_S You can actually do this even more easily now with the new-to-KM 10 sort filter:


Hmmm... I skipped that because of the Wiki entry:

  • Sort, reverse sort, or shuffle lines.

...but it seems that the "Reverse" option is a true reverse and not a reverse sort (which I guess would be two filter actions -- sort then reverse).

Thanks for the eye-opener, @gglick!

1 Like

I love when I learn that something like this is just built-in. Thank you for pointing it out for me!

1 Like