I am looking to do something like this in KSH:

if (( $var = (foo|bar)[0-9]*$ )); then
    print "variable matched regex"

Is it possible at all?

For the record I'm using Ksh Version M-11/16/88i on a Solaris 10 machine.

  • 4
    Do you realize the regular expression [foo|bar] means "match a single character from the set (a,b,f,o,r,|)"? If you mean "match 'foo' or 'bar'" you want (foo|bar) Commented Oct 19, 2011 at 14:20
  • True, didn't notice that. I will update accordingly.
    – rahmu
    Commented Oct 19, 2011 at 14:26

5 Answers 5


Ksh has regular expressions, but not in the usual syntax (not in the version in Solaris 10).

if [[ $var = *@(foo|bar)*([0-9]) ]]; then …

In the manual, look under “conditional expressions” for what's inside the brackets and under “file name generation” for the pattern syntax.

  • This is a pattern match, not a regular expression match (which uses the =~ operator).
    – chepner
    Commented Nov 6, 2015 at 22:42
  • 1
    @chepner It doesn't use regex syntax, but it is a regular expression. Ksh patterns include all regular expression operators. Commented Nov 6, 2015 at 22:47
  • what does the *@ in the regular expression stands for ?
    – Ali BENALI
    Commented Aug 23, 2021 at 10:27
  • 1
    @Ali In the ksh regular expression syntax (which is not the usual regex syntax), * stands for any sequence of characters and @(foo|bar) matches either foo or bar. Commented Aug 23, 2021 at 21:20
  • In this case, the *([0-9]) says to match zero or more occurrences of what is in the parens, NOT any sequence of characters. Observe, the regexp will not pass var="bar##3". Meanwhile, it will pass var if we have to have zero or more digits. as in var="bar321" Commented Jan 6, 2022 at 0:04

Using case with glob patterns might work for you. The composite pattern *(pattern-list) means "Matches zero or more occurrences of the given patterns" and @(pattern-list) means "Matches exactly one of the given patterns."

matcher() {
  typeset var="$1"
  case "$var" in
    *@(foo|bar)*([0-9])) print "$var matched" ;;
    *) print "$var did not match" ;;

for var in foo bar baz foo123 abc_foo132 abc_foo123z bar1 1bar1 1bar1a; do 
  matcher "$var"


foo matched
bar matched
baz did not match
foo123 matched
abc_foo132 matched
abc_foo123z did not match
bar1 matched
1bar1 matched
1bar1a did not match

Why not use egrep(1)? Gives you all a regex user could wish for:

 if echo "$var" | egrep -s '(foo|bar)[0-9]*$'    # -s means "silent"

Additional note for Solaris: With Solaris you may want to check the manpage for egrep - there is annother egrep version that is located at /usr/xpg4/bin/egrep that supports some more options and differs in functionality when it comes to advanced regex stuff.

  • 1
    sometimes Solaris will have GNU Egrep installed as well, as gegrep. Either from the Companion CD, or from SunFreeWare, and usually in /opt/sfw/bin or /usr/local/bin. Commented Oct 20, 2011 at 19:52
  • @Tim: true, but I'd never rely on that. From my experience with customer production systems you'd better stick to what the base OS provides since what we would consider cool and helpful is often not allowed in production. +1 anyway ;-)
    – ktf
    Commented Oct 21, 2011 at 11:50
  • 100% agreed. i try to always use scripts/programs/perl modules that are installed by default. keeps things portable. Commented Oct 22, 2011 at 4:57

I did something like this, using sed. I don't know how good it is, but at least it worked ^^

if [ -z "$(echo "$var" | sed -e 's/(foo|bar)[0-9]*$//')" ]; then
    print "variable matched regex"
  • You need to put double quotes around variable substitutions, as always (otherwise you'll get wrong results or errors on some inputs containing wildcard characters or whitespace). Even with the right quoting, this assumes that the input doesn't contain a newline. Furthermore, your method is highly convoluted; grep is more natural, but there's a way that's built into ksh. Commented Oct 20, 2011 at 16:47

I know I'm late to the party, but instead of ktf's solution:

 if echo "$var" | egrep -s '(foo|bar)[0-9]*$'    # -s means "silent"

you may also use

 if grep -q '(foo|bar)[0-9]*$' <<< "$var"        # -q means "quiet" ;-)

This technique with the <<< operator is called the herestring. However, I should also add a warning: this WON'T work under a read-only environment (i. e. you will get ugly error messages to stderr), since the herestring requires a temporary file to be written to somewhere. As far as I know, the "classic" way with echo and a pipe will also work without any write permission at all.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .