102

I'm writing a script in Unix where I have to check whether the first character in a string is "/" and if it is, branch.

For example, I have a string:

/some/directory/file

I want this to return 1, and:

server@10.200.200.20:/some/directory/file

to return 0.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
canecse
  • 1,772
  • 3
  • 16
  • 20
  • [How to check if a string begins with some value in Bash?](https://stackoverflow.com/q/2172352/608639). – jww Nov 01 '19 at 16:32

5 Answers5

182

There are many ways to do this. You could use wildcards in double brackets:

str="/some/directory/file"
if [[ $str == /* ]]; then echo 1; else echo 0; fi

You can use substring expansion:

if [[ ${str:0:1} == "/" ]] ; then echo 1; else echo 0; fi

Or a regex:

if [[ $str =~ ^/ ]]; then echo 1; else echo 0; fi
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user000001
  • 32,226
  • 12
  • 81
  • 108
20

Consider the case statement as well which is compatible with most sh-based shells:

case $str in
/*)
    echo 1
    ;;
*)
    echo 0
    ;;
esac
konsolebox
  • 72,135
  • 12
  • 99
  • 105
  • 1
    I thought glob `*` only matches a single path component, never across slashes `/` – user1011471 Jun 01 '15 at 16:51
  • 1
    The relevant POSIX quote is: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html "Case Conditional Construct" sentence "corresponding to the first one of several patterns (see Pattern Matching Notation)" – Ciro Santilli OurBigBook.com Aug 07 '18 at 07:02
  • 1
    Also if you want to match a `#` you'll have to use quotes. For example: `'#'*) echo "found comment";;`. – Alexis Wilke Jul 01 '20 at 01:06
  • I happen to have to write POSIX-compliant code (/bin/sh) thus @konsolebox's answer (although quite old) was most useful, thanks @konsolebox! – yassen Oct 12 '21 at 06:26
12
$ foo="/some/directory/file"
$ [ ${foo:0:1} == "/" ] && echo 1 || echo 0
1
$ foo="server@10.200.200.20:/some/directory/file"
$ [ ${foo:0:1} == "/" ] && echo 1 || echo 0
0
devnull
  • 118,548
  • 33
  • 236
  • 227
  • 5
    Downvote! You forgot to quote your variable in single braces. ``foo='*'; [ ${foo:0:1} == "/" ] && echo 1 || echo 0`` is going to output this error ``bash: [: too many arguments``. Use ``[ "${foo:0:1}" == "/" ] && echo 1 || echo 0`` or even better ``[[ ${foo:0:1} == "/" ]] && echo 1 || echo 0`` – Aleks-Daniel Jakimenko-A. Aug 28 '13 at 14:31
  • @Aleks-DanielJakimenko-A. - devnull's answer works without error in "GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu) Copyright (C) 2013 Free Software Foundation, Inc." – Craig Hicks Apr 20 '18 at 11:20
  • Your initial expression: "Downvote! You forgot to quote your variable in single braces." implies that the expressions entered in devnulls answer won't work as is on bash. You need to modify that initial expression in order to properly deliver your technical point, otherwise it isn't logically correct. – Craig Hicks Apr 21 '18 at 16:49
  • 3
    @Mausy5043 it's not a “typo”, it is buggy and incorrect. – Aleks-Daniel Jakimenko-A. Aug 06 '18 at 08:57
9

printf '%c "$s"

This was mentioned by brunoais in a comment, and it might be the best option since:

  • it is likely POSIX. TODO confirm. The following quote from https://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html suggests this:

    It shall not be considered an error if an argument operand is not completely used for a b, c, or s conversion.

  • it can extract the character to a variable unlike using case directly

  • unlike cut -c1 printf is a Bash built-in so it could be a little bit faster

myvar=abc
first_char="$(printf '%c' "$myvar")"
if [ "$first_char" = a ]; then
  echo 'starts with a'
else
  echo 'does not start with a'
fi

cut -c1

This is POSIX, and unlike case:

myvar=abc
first_char="$(printf '%s' "$myvar" | cut -c1)"
if [ "$first_char" = a ]; then
  echo 'starts with a'
else
  echo 'does not start with a'
fi

awk substr is another POSIX command, but less efficient alternative:

printf '%s' "$myvar" | awk '{print substr ($0, 0, 1)}'

printf '%s' is to avoid problems with escape characters: Bash printf literal verbatim string, e.g.,

myvar='\n'
printf '%s' "$myvar" | cut -c1

outputs \ as expected.

${::} does not seem to be POSIX.

See also: How can I extract the first two characters of a string in shell scripting?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
3

Code:

 place="Place"
 fchar=${place:0:1}
 echo $fchar

Output:

P
naqviO7
  • 41
  • 4