I am trying to compare two "almost" identical strings in a shell script.
They are similar except for one character (A-Z).
In the example below I want the code to return true for all cases of the string from
1-2-3-A-5-6-
to 1-2-3-Z-5-6-
Currently my code returns false.
#!/bin/bash
TEMPLATE='1-2-3-*-5-6-'
CASE='1-2-3-A-5-6-'
if [[ "$TEMPLATE" == "$CASE" ]]; then
echo "It's there."
else
echo "NO, improve!"
fi
The pattern 1-2-3-*-5-6-
is a glob.
This pattern language is described in the Pattern Matching section of the bash manual, and available to both the [[ == ]]
test you're trying to use (manual quoted below), and the case
version mentioned in a comment.
[[ expression ]]
... 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, as if the extglob shell option were enabled. The=
operator is equivalent to==
. If the nocase‐ match shell option is enabled, the match is performed without regard to the case of alphabetic characters.
... Any part of the pattern may be quoted to force the quoted portion to be matched as a string.
There are only two constraints:
you can't quote the pattern if you want it to be matched as a pattern rather than a literal string
(see the last quoted paragraph)
the pattern must go on the right hand side of the operator
(first paragraph)
So your code will work fine as
#!/bin/bash
TEMPLATE='1-2-3-*-5-6-'
CASE='1-2-3-A-5-6-'
if [[ $CASE == $TEMPLATE ]]; then
echo "It's there."
else
echo "NO, improve!"
fi
NB. Part of the reason for using the built-in [[ ]]
conditions instead of the old [ ]
ones is specifically that
Word splitting and pathname expansion are not performed on the words between the
[[
and]];
so you don't generally need to quote variables (and in this particular case, must not quote at least one of them).