harryz
harryz

Reputation: 5290

How to test if string matches a regex in POSIX shell? (not bash)

I'm using Ubuntu system shell, not bash, and I found the regular way can not work:

#!/bin/sh
string='My string';

if [[ $string =~ .*My.* ]]
then
   echo "It's there!"
fi

error [[: not found!

What can I do to solve this problem?

Upvotes: 36

Views: 29600

Answers (3)

gavenkoa
gavenkoa

Reputation: 48893

Using grep for such a simple pattern can be considered wasteful. Avoid that unnecessary fork, by using the Sh built-in Glob-matching engine (NOTE: This does not support regex):

case "$value" in
  *XXX*)  echo OK ;;
  *) echo fail ;;
esac

It is POSIX compliant. Bash have simplified syntax for this:

if [[ "$value" == *XXX* ]]; then :; fi

and even regex:

[[ abcd =~ b.*d ]] && echo ok

Upvotes: 31

devnull
devnull

Reputation: 123608

You could use expr:

if expr "$string" : "My" 1>/dev/null; then
  echo "It's there";
fi

This would work with both sh and bash.

As a handy function:

exprq() {
  local value

  test "$2" = ":" && value="$3" || value="$2"
  expr "$1" : "$value" 1>/dev/null
}

# Or `exprq "somebody" "body"` if you'd rather ditch the ':'
if exprq "somebody" : "body"; then 
  echo "once told me"
fi

Quoting from man expr:

   STRING : REGEXP
          anchored pattern match of REGEXP in STRING

Upvotes: 14

Christopher Neylan
Christopher Neylan

Reputation: 8282

The [[ ... ]] are a bash-ism. You can make your test shell-agnostic by just using grep with a normal if:

if echo "$string" | grep -q "My"; then
    echo "It's there!"
fi

Upvotes: 40

Related Questions