Case insensitive comparison of strings in shell script
StringShellCompareCase InsensitiveString Problem Overview
The ==
operator is used to compare two strings in shell script. However, I want to compare two strings ignoring case, how can it be done? Is there any standard command for this?
String Solutions
Solution 1 - String
In Bash, you can use parameter expansion to modify a string to all lower-/upper-case:
var1=TesT
var2=tEst
echo ${var1,,} ${var2,,}
echo ${var1^^} ${var2^^}
Solution 2 - String
All of these answers ignore the easiest and quickest way to do this (as long as you have Bash 4):
if [ "${var1,,}" = "${var2,,}" ]; then
echo ":)"
fi
All you're doing there is converting both strings to lowercase and comparing the results.
Solution 3 - String
if you have bash
str1="MATCH"
str2="match"
shopt -s nocasematch
case "$str1" in
$str2 ) echo "match";;
*) echo "no match";;
esac
otherwise, you should tell us what shell you are using.
alternative, using awk
str1="MATCH"
str2="match"
awk -vs1="$str1" -vs2="$str2" 'BEGIN {
if ( tolower(s1) == tolower(s2) ){
print "match"
}
}'
Solution 4 - String
Save the state of nocasematch
(in case some other function is depending on it being disabled):
local orig_nocasematch=$(shopt -p nocasematch; true)
shopt -s nocasematch
[[ "foo" == "Foo" ]] && echo "match" || echo "notmatch"
$orig_nocasematch
>Note that local
is only required inside a function.
>Also, the ; true
part will prevent the shell from exiting when set -e
is on and $(shopt -p nocasematch)
fails (because nocasematch was NOT set at all).
Solution 5 - String
One way would be to convert both strings to upper or lower:
test $(echo "string" | /bin/tr '[:upper:]' '[:lower:]') = $(echo "String" | /bin/tr '[:upper:]' '[:lower:]') && echo same || echo different
Another way would be to use grep:
echo "string" | grep -qi '^String$' && echo same || echo different
Solution 6 - String
For korn shell, I use typeset built-in command (-l for lower-case and -u for upper-case).
var=True
typeset -l var
if [[ $var == "true" ]]; then
print "match"
fi
Solution 7 - String
Very easy if you fgrep to do a case-insensitive line compare:
str1="MATCH"
str2="match"
if [[ $(fgrep -ix $str1 <<< $str2) ]]; then
echo "case-insensitive match";
fi
Solution 8 - String
For zsh
the syntax is slightly different, but still shorter than most answers here:
> str1='mAtCh'
> str2='MaTcH'
> [[ "$str1:u" = "$str2:u" ]] && echo 'Strings Match!'
Strings Match!
>
This will convert both strings to uppercase before the comparison.
Another method makes use zsh's globbing flags
, which allows us to directly make use of case-insensitive matching by using the i
glob flag:
setopt extendedglob
[[ $str1 = (#i)$str2 ]] && echo "Match success"
# this example compares the variable with a literal string 'match'
[[ $str1 = (#i)match ]] && echo "Match success"
Solution 9 - String
I came across this great blog/tutorial/whatever about dealing with case sensitive pattern. The following three methods are explained in details with examples:
1. Convert pattern to lowercase using tr command
opt=$( tr '[:upper:]' '[:lower:]' <<<"$1" )
case $opt in
sql)
echo "Running mysql backup using mysqldump tool..."
;;
sync)
echo "Running backup using rsync tool..."
;;
tar)
echo "Running tape backup using tar tool..."
;;
*)
echo "Other options"
;;
esac
2. Use careful globbing with case patterns
opt=$1
case $opt in
[Ss][Qq][Ll])
echo "Running mysql backup using mysqldump tool..."
;;
[Ss][Yy][Nn][Cc])
echo "Running backup using rsync tool..."
;;
[Tt][Aa][Rr])
echo "Running tape backup using tar tool..."
;;
*)
echo "Other option"
;;
esac
3. Turn on nocasematch
opt=$1
shopt -s nocasematch
case $opt in
sql)
echo "Running mysql backup using mysqldump tool..."
;;
sync)
echo "Running backup using rsync tool..."
;;
tar)
echo "Running tape backup using tar tool..."
;;
*)
echo "Other option"
;;
esac
shopt -u nocasematch
Solution 10 - String
grep
has a -i
flag which means case insensitive so ask it to tell you if var2 is in var1.
var1=match
var2=MATCH
if echo $var1 | grep -i "^${var2}$" > /dev/null ; then
echo "MATCH"
fi
Solution 11 - String
Here is my solution using tr:
var1=match
var2=MATCH
var1=`echo $var1 | tr '[A-Z]' '[a-z]'`
var2=`echo $var2 | tr '[A-Z]' '[a-z]'`
if [ "$var1" = "$var2" ] ; then
echo "MATCH"
fi
Solution 12 - String
shopt -s nocaseglob
Solution 13 - String
On Unix-like operating systems, the test command checks file types and compares values.
str1="MATCH"
str2="match"
if test $str1 = $str2
then
echo "equal yes"
else
echo "equal not"
fi
On Unix-like operating systems, the test command checks file types and compares values.
it's very simple that way.
in a few lines of code
Solution 14 - String
The 'tr' utility (translate characters) is always present on all Unix/Linux machines, and is light-weight.
Here is a function that can be used to address case insensitive comparisons. Since the exact location of 'tr' can vary, we first probe its likely locations and store the correct location in an env var appropriately named "BIN_TR".
declare BIN_TR=$( ls /bin/tr /usr/bin/tr 2>/dev/null | head -1 );
That is then used in the function declaration.
toLowerCase() {
echo "$*" | $BIN_TR '[:upper:]' '[:lower:]'
}
A solution using 'tr' is expected to be highly portable between different variations of OS and OS set-up. While 'awk' is also highly probable, the 'tr' utility is tiny compared to 'awk', and so a function using 'tr' is presumably lighter weight.