8

JavaScript has a function for this:

'world'.startsWith('w')
true

How can I test this with shell? I have this code:

if [ world = w ]
then
  echo true
else
  echo false
fi

but it fails because it is testing for equality. I would prefer using a builtin, but any utilities from this page would be acceptable:

http://pubs.opengroup.org/onlinepubs/9699919799/idx/utilities.html

3 Answers 3

12

If your shell is bash: within double brackets, the right-hand side of the == operator is a pattern unless fully quoted:

if [[ world == w* ]]; then
    echo true
else
    echo false
fi

Or more tersely: [[ world == w* ]] && echo true || echo false [*]

If you are not targetting bash specifically: use the case statement for pattern matching

case "world" in
    w*) echo true ;;
    *)  echo false ;;
esac

[*] but you need to be careful with the A && B || C form because C will be executed if either A fails or B fails. The if A; then B; else C; fi form will only execute C if A fails.

6

Set a variable to that value (here we set $str to world):

str=world

Then:

if [ -n "${str%%w*}" ]
then
  echo false
else
  echo true
fi
  1. Aggressively remove the pattern w* from the start of $str. w* matches w followed by any number of characters, so it'll match the whole string if possible.
  2. If anything is left, then $str does not start with w.

Or:

if [ "$str" = "${str#w}" ]
then
  echo false
else
  echo true
fi
  1. Remove w from $str, if possible.
  2. Compare with $str.
  3. If equal (i.e. the removal did nothing), then $str does not start with w.
1
  • The first code snippet does not work if str is already empty. Commented Oct 24, 2023 at 14:41
5

The standard sh syntax for that is with a case construct:

string=world
start=w
case $string in
  ("$start"*) printf '%s\n' "$string starts with $start";;
  (*)         printf '%s\n' "$string does not start with $start";;
esac

Note the quotes around $start which are necessary in the cases where $start contains wildcard characters. For instance, with start='*', without them, $start* would always match. Same goes for the [[ $string = "$start"* ]] of ksh/bash.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.