Remove All Numbers After ' \ ', Including the ' \ '

Thanks in advance for your help ... I can't seem to figure out this most basic macro.

In my variable 'initial_input', I have 33/124. All I'd like to do is remove the '/124' bit so that I'm left with '33' in a new variable 'final_input'.

Note that sometimes the initial_input will have 0/233 or sometimes a much longer number like 23443/100322.

How can remove the '/' and any numbers thereafter with regex?

Thanks again!

Hi @jcastleden,

This will work.

1 Like

This is another way to accomplish it: just search for the numbers before the /.

1 Like

Thank you so much for your help! The second suggestion is actually exactly what I need :slight_smile:

Hi and welcome to the forums!

I only know how to do this with a shell script. Someone else who knows more about working with regex in Keyboard Maestro might have a more “native” answer, and hopefully, they will add their answer as well.

(Note: it took me so long to write this, someone else did exactly that. Oh well. I’ve learned something from them, and will leave this here in case anyone else finds it interesting.)

Here's what I came up with:
Take Input Remove Slash and Everything After It.kmmacros (2.6 KB)

(You can click on that :arrow_up: to download it, and then double-click to import it into Keyboard Maestro.)

Here's a screenshot with some numbers we'll use as reference points:

(I’m not sure of your experience level with Keyboard Maestro so I’m going to write this assuming none. Please take no offense, even if you don’t need all of this explained, someone else might.)

  1. This is the keyboard shortcut that I assigned, which is the command key plus return. Obviously, feel free to edit that.

  2. This will be the title of the input window which is shown to the user.

  3. This will be the sub-title of the input window

  4. This is the variable name. It can be whatever you like. I use ALL_CAPS with an _ between words, but you can use whatever you prefer.

  5. This is the default value. It is probably best to leave this blank, but I wanted to be able to show how it works even for someone who wasn't sure what it was going.

  6. This is the text that will be shown on the “Yes, Go Ahead, Do It” button

  7. This is the text that will be shown on the “No, on second thought, don’t do it” button.

  8. With this option set, if someone chooses #7, it will cancel the macro

  9. You can click here to show other things you can do with the result, including saving it to the clipboard (useful) or saving it to another Keyboard Maestro variable (also useful). The option I've chosen is less useful, except for the purposes of this exercise.

  10. When using a Keyboard Maestro variable in a shell script, there are two important things to remember:

    • Be sure to add $KMVAR_ as a prefix before the variable name
    • ALWAYS ALWAYS ALWAYS put "double quotes" around the whole thing, so:
Good and Bad Examples Outcomes
echo "$KMVAR_SLASH_NUMBER" :white_check_mark: Good
echo '$KMVAR_SLASH_NUMBER' :no_entry_sign: Wrong - single quotes won't work
echo $KMVAR_SLASH_NUMBER :no_entry_sign: Wrong - missing double quotes
echo "$SLASH_NUMBER" :no_entry_sign: Wrong - missing $KMVAR_ prefix
  1. This is where we process the variable using the Unix sed command.

sed will take input and can either delete or change it before sending it to output. When you are doing these sorts of replacements in sed you use s at the beginning and g at the end. What you want to match and what you want to replace it with are separated by #

This gives us the basic format of this:

sed 's#A#B#g'

Where A represents what we want to match and B represents what we want to replace it with.

(Note that you do not have to use # you could use / or other punctuation, but for the sake of clarity, I like to use # unless I am trying to replace something that has a # in it.)

Examples

So, for example, if I did this:

echo apple orange grapefruit banana | sed 's#apple#PEACH#g'

the output would be

PEACH orange grapefruit banana

Notice that the word on the right has replaced the word on the left.

But it doesn't have to be complete words. If I wanted to change all of the a characters to A I could do this:

echo apple orange grapefruit banana | sed 's#a#A#g'

and get

Apple orAnge grApefruit bAnAnA

Note that all of the matching a characters are now A.

If I want to delete the word 'grapefruit' I would do this:

echo apple orange grapefruit banana | sed 's#grapefruit##g'

Notice that there is nothing on the right side. What we're basically saying is “replace the word grapefruit with nothing.”

This is what we would get:

apple orange  banana

It may be difficult to see on a webpage, but there are two spaces between orange and banana because there was a space before and after the word grapefruit.

Getting Closer…

If I want to delete the word grapefruit and anything that comes after it then I would use a period and an asterisk: .* like this:

echo apple orange grapefruit banana | sed 's#grapefruit.*##g'

which means "replace the word 'grapefruit and anything that comes after it with nothing" which effectively deletes it.

So, for your example:

You want to take the input and delete / and anything after it, so you want to use /.*

echo "$KMVAR_SLASH_NUMBER" | sed 's#/.*##g'

Voilà!

I hope this helps or at least has been slightly amusing/educational :slight_smile:

1 Like

That's an extremely detailed explanation; thank you so much for your efforts. I'm slowly getting my head around RegEx (it really is very powerful) and other advanced features and your post is going to help me immensely!

2 Likes

Up to slash.kmmacros (18.3 KB)

Mileage varies, but a JS incantation always seems simpler and more flexible to me than a regular expression:

2 Likes

Hey Martin,

This is exactly the way I'd normally tackle this job, except..

I'd write the regular expression like this:

^(\d+)/

I prefer the metacharacter for digit (\d) to using the character class notation.

I'm also anchoring to the beginning of the line for added safety.

-Chris

1 Like

Hey TJ,

Nice write-up!

I use Sed quite a lot, although Gnu Sed beats the pants off the macOS' ancient BSD version.

As I mention above I'd almost certainly turn to Keyboard Maestro's Search with RegEx action for this little job – but were I to use the shell I might turn away from Sed this time – IF I was certain sure of the structure of the input.

Awk lets you reassign the field-separator and print a given field.

Cut does the same thing, except it calls the separator a delimiter.

I'm using Here Strings notation to provide the input instead of echo, because I prefer the way it reads.

-Chris

#!/usr/bin/env bash
myVar='33/124'

awk 'BEGIN { FS = "/" }; { print $1 }' <<< "$myVar"

Result: 33

# -------------------------------------------------

#!/usr/bin/env bash
myVar='33/124'

cut -d '/' -f 1 <<< "$myVar"

Result: 33
1 Like

Thanks, Chris. I've always been using \d. I don't know why I used [0-9] at that moment. :joy:

1 Like

Oh definitely. But I try not to suggest solutions that would require someone installing something else. My whole collection of download and install scripts for macOS is intentionally designed to use only the default macOS Unix tools because I want them to be usable on a new install. (For some of them I do use lynx if it is available, but usually only for parsing release notes because I’m not foolish enough to try to write my own HTML parser.)

awk is a tool that I wish I knew better but I only know 1/1000th of what it can do.

cut would be a good choice for this too. Not sure why I didn’t think of that one.

Agreed. Everything I post to the forum is turnkey, unless I have to use a 3rd party tool.

Nevertheless I want people to be aware of such things.

Homebrew is extremely easy to use, and while MacPorts (which I use) has a bigger learning curve it's not horrible.

Having more modern tools available means getting more work done more efficiently – aside from keeping up with the Joneses...

Most Mac users don't even know such things exist, so we need to at illuminate the fact that they have options.

-Chris

I do stuff like that from time to time.

What idiot wrote that? Oh, it was me...  :sunglasses:

Here's an example of why I'm anchoring to the beginning of the line in my regex above.

Keyboard Maestro Actions.kmactions (1.6 KB)

While @jcastleden's use-case probably will never have to deal with something like that, I like to take precautions.

One rule-of-the-thumb with regular expression is to keep them reasonably simple when possible.

Never write a hugely complex regex when 2-3 simple ones will do the job.

What if your input data looks like this:

Keyboard Maestro Actions.kmactions (1.4 KB)

While I would normally use a regular expression to clean this up, @peternlewis has provided a nice little filter to do the job for you.

To do it with RegEx I'd use two steps:

Keyboard Maestro Actions.kmactions (2.3 KB)

The quotes are in the Display-text-in-a-window action, because it automatically trims whitespace from the data it is given – and this can make you lose your mind when testing data-processing methods and getting unexpected results that aren't your fault.

The quotes make the action leave in any whitespace in the data.

I often preprocess data to correct irregularities, before I get down to the nitty gritty work.

Another common issue with input data is end-of-line characters that are unexpected and unseen.

You can easily get bitten by this one, unless you open data and eyeball it with a hex editor – or your text editor properly distinguishes between them with invisibles turned on. (One of my few disappointments with BBEdit is that it treats CR and LF characters the same.)

You might have carriage returns when you expected linefeeds, or you might have a Windows-style mix of the two.

Thankfully Peter has filters to manage EOL characters, but they're easy enough to handle with RegEx if you prefer.

Hmm.  Brain fog rolling in from the South.

Chris needs some dinner...

1 Like