Tony
Tony

Reputation: 31

Regarding Bash substring comparison

I try to test if a string starts with a certain prefix. But my script seems not work (I would expect the "if" branch will not get run). Can some Bash expert help to take a look? thanks!

Here is my code and test result:

$ cat testb.bash

#!/bin/bash

my_var="abcdefg";
if [[ "${my_var:0:5}"=="order" ]]; then
    echo "value of my_var is ${my_var}.";
fi;

if [[ "${my_var:0:5}" -eq "order" ]]; then
    echo "value of my_var is ${my_var}.";
fi;

if [ "${my_var:0:5}"="order" ]; then
    echo "value of my_var is ${my_var}.";
fi;

$ bash -x testb.bash

+ my_var=abcdefg
+ [[ -n abcde==order ]]
+ echo 'value of my_var is abcdefg.'            
value of my_var is abcdefg.
+ [[ abcde -eq order ]]
+ echo 'value of my_var is abcdefg.'
value of my_var is abcdefg.
+ '[' abcde=order ']'
+ echo 'value of my_var is abcdefg.'
value of my_var is abcdefg.
$

Upvotes: 0

Views: 171

Answers (4)

fedorqui
fedorqui

Reputation: 290095

To test the existence of substring, you can use either of these:

if [[ "$j" =~ string1 ]]; then
if [[ $j == *string1* ]]; then

In your particular case, you miss a space surounding ==, so instead of

if [[ "${my_var:0:5}"=="order" ]]; then

it should be

if [[ "${my_var:0:5}" == "order" ]]; then
                     ^  ^

Finally, note that your condition was evaluated as true because it was evaluating if [ "string" ], which is true if string is not empty:

$ [ "a" ] && echo "yes"
yes

Test

$ cat a
#!/bin/bash

my_var="abcdefg";
if [[ "${my_var:0:5}" == "order" ]]; then
    echo "value of my_var is ${my_var}."
elif [[ "${my_var:0:5}" == "abcde" ]]; then
    echo "yeahaa"
else
    echo "is not"
fi

$ ./a
yeahaa

Upvotes: 2

chepner
chepner

Reputation: 531878

A POSIX-compliant way to test for a prefix is to attempt to remove the prefix, and compare the result to the original string. If the two are the same, the prefix is not present, the removal fails, and the expression expands to the original string.

prefix=foo
string=foobar

if [ "${string#$prefix}" = "$string" ]; then
    printf "$string does not start with $prefix\n"
else
    printf "$string starts with $prefix\n"
fi

Upvotes: 0

PersianGulf
PersianGulf

Reputation: 2935

Ok, i tested your code, you shoud such as the following code:

prefix="pre_order";
pre="pre_"
len=${#pre}
echo $len
if [[ "${prefix:0:len}" == "blahvlah" ]] ;  then
 echo "dddd"
fi;

Notes:

  1. use == for string comparation
  2. for ${} you should initilize a string variable before ${}
  3. use len=${#pre} for lenght of string.

Upvotes: 1

choroba
choroba

Reputation: 241998

Whitespace is significant in this case. As you can see in the -x output, it understands the first condition as

[[ -n "${my_var:0:5}==order" ]]

Moreover, to test for a prefix, you can use a pattern:

[[ $my_var == order* ]]

Upvotes: 2

Related Questions