Yes. I think you would have to be paid for your work here, in order to fire you
While I appreciate the desire to have a solution that uses native Keyboard Maestro commands, when you're processing lines of text, it's hard to beat the old Unix tools. Printing out just one of many lines is the kind of thing sed
was made for. For example, to print the 5th line of a file, do
sed -n '5 p' file.txt
This can be generalized to use a KM variable.
Here, the sed
command is
sed -n "$KMVAR_InstanceWhichLine p"
where the trick is to use double quotes to make sure the environment variable is interpolated.
And here's one that uses AppleScript. A benefit of this one is if you want the last line just specify -1
; the next-to-last use -2
, etc. (something that's also true of the KM variable array approach...)
[LIB]_Get Line from List.kmmacros (4.6 KB)
Though why use sed
when you can have so much fun with awk
?
awk 'NR == 5 {print; exit}' someFile.txt
No idea why it's my favourite – just seems to be.
I suspect, however, that Keyboard Maestro's tokens with [indexes] and trailling custom delimiters do a better job with Unicode.
Oh, I did one with awk
, although I didn’t include the exit
command, thus increasing the runtime by nanoseconds. Also a head | tail
pipeline.
As for splitting on anything other than linefeed, you’re right: shell one-liners aren’t the right tool.
Counting backwards from the end is a nice addition and something (I'm pretty sure) sed
can't do .
Who would have thought that finding ways of splitting text lines could give us all so much happiness? But it does.
Keyboard Maestro can.
%Variable%Source[-3]KM,KM%
Peter's solution works for the Nth last string in a series of strings on a single line (usually the comma is the delimiter) but if you want KM to give you the Nth last line in a multi-line variable, without resorting to external scripts, you can do it this way:
This is a variation of the solution I posted above for finding the Nth line. But when counting backwards like this, you have to be careful that the last line of your file ends with a newline, or you might miss your desired line by one. I suppose you could account for that by changing this action.
I should have posted the macro in this thread. But since I've deleted it, I'll retype the important line for everyone here:
([^\n]+\n)*(.*\n){%Calculate%Nth-1%}$
As I mentioned in my post:
And of course by using the array’s zero index [0]
you can also get the total number of items (in this case, lines) in the variable.
Thanks @DanThomas for the link to https://github.com/ziishaned/learn-regex. I've been wanting to learn regex but did not know where to start other than https://regex101.com and I did not want to just sit and play with expressions in regex101 in an unstructured way.
Cool! You might try and document your progress, so you can share it with others. On the other hand, maybe just learning regex is enough of an effort, just by itself.
Yes, and I’ve learned more about KM lists from this thread than I ever knew before.
On the other hand, I was looking for a one-action, one-line solution. Until you get the \n
syntax working, KM still requires a find/replace action first.
If you do it my way, post #28, KM does not require a find/replace action first. My solution was a one-action, one-line solution.
I made a plug-in to get the Nth line from the source string:
I don't use it often. If you are interested, I can share it.
Hey Folks,
Here are some turnkey macros.
-Chris
Awk to Extract a Line by Number v1.00.kmmacros (6.2 KB)
Sed to Extract a Line by Number v1.00.kmmacros (6.2 KB)
Perl to Extract a Line by Number v1.00.kmmacros (6.3 KB)
The JXA macro allows splitting the data-string into an array with a regular expression and is therefore not limited to using linefeed delimited data.
FWIW, a Haskell solution using this plugin:
If I want the second line, perhaps:
Get Nth Line.kmmacros (1.9 KB)
Great. It often seems to be the case that Variables are multi-line and being able to directly reference those lines like this will simplify things a lot. Thank you!