The need to compare strings in a Bash script is relatively common and can be used to check for certain conditions before proceeding on to the next part of a script. A string can be any sequence of characters. To test if two strings are the same, both strings must contain the exact same characters and in the same order.
You should not use == (equality operator) to compare these strings because they compare the reference of the string, i.e. whether they are the same object or not. On the other hand, equals() method compares whether the value of the strings is equal, and not the object itself.
Use the equals() method to check if 2 strings are the same. The equals() method is case-sensitive, meaning that the string "HELLO" is considered to be different from the string "hello". The == operator does not work reliably with strings. Use == to compare primitive values such as int and char.
Try this: http://tldp.org/LDP/abs/html/comparison-ops.html
string comparison
=
is equal to
if [ "$a" = "$b" ]
There is a difference in testing for equality between [ ... ]
and [[ ... ]]
.
The [ ... ]
is an alias to the test
command:
STRING1 = STRING2 the strings are equal
However, when using [[ ... ]]
When the
==
and!=
operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below under Pattern Matching. If the shell option nocasematch is enabled, the match is performed without regard to the case of alphabetic characters. The return value is 0 if the string matches (==
) or does not match (!=
) the pattern, and 1 otherwise. Any part of the pattern may be quoted to force it to be matched as a string.
The same seems to be true with just the =
sign:
$ foo=bar
$ if [[ $foo = *ar ]]
> then
> echo "These patterns match"
> else
> echo "These two strings aren't equal"
> fi
These patterns match
Note the difference:
$ foo=bar
> if [ $foo = *ar ]
> then
> echo "These patterns match"
> else
> echo "These two strings aren't equal"
> fi
These two strings aren't equal
However, there are a few traps with the [ $f00 = *ar ]
syntax. This is the same as:
test $foo = *ar
Which means the shell will interpolate glob expressions and variables before executing the statement. If $foo
is empty, the command will become equivalent to:
test = *ar # or [ = *ar ]
Since the =
isn't a valid comparison operator in test
, you'll get an error like:
bash: [: =: unary operator expected
Which means the [
was expecting a parameter found in the test
manpage.
And, if I happen to have a file bar
in my directory, the shell will replace *ar
with all files that match that pattern (in this case bar
), so the command will become:
[ $foo = bar ]
which IS true.
To get around the various issues with [ ... ]
, you should always put quotes around the parameters. This will prevent the shell from interpolating globs and will help with variables that have no values:
[ "$foo" = "*ar" ]
This will test whether the variable $foo
is equal to the string *ar
. It will work even if $foo
is empty because the quotation marks will force an empty string comparison. The quotes around *ar
will prevent the shell from interpolating the glob. This is a true equality.
Of course, it just so happens that if you use quotation marks when using [[ ... ]]
, you'll force a string match too:
foo=bar
if [[ $foo == "*ar" ]]
then
echo "This is a pattern match"
else
echo "These strings don't match"
fi
So, in the end, if you want to test for string equality, you can use either [ ... ]
or [[ ... ]]
, but you must quote your parameters. If you want to do glob pattern matching, you must leave off the quotes, and use [[ ... ]]
.
To compare two strings in variables x
and y
for equality, use
if test "$x" = "$y"; then
printf '%s\n' "equal"
else
printf '%s\n' "not equal"
fi
To test whether x
appears somewhere in y
, use
case $y in
(*"$x"*)
printf '%s\n' "$y contains $x"
;;
(*)
printf '%s\n' "$y does not contain $x"
;;
esac
Note that these constructs are portable to any POSIX shell, not just bash. The [[ ]]
construct for tests is not (yet) a standard shell feature.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With