bash - case-insensitive matching of variable

Standard sh

No need to use that ksh-style [[...]] command, you can use the standard sh case construct here:

case $LINUX_CONF in
  ([Nn][Oo]) echo linux;;
  (*)        echo not linux;;
esac

Or naming each possible case individually:

case $LINUX_CONF in
  (No | nO | NO | no) echo linux;;
  (*)                 echo not linux;;
esac

bash

For a bash-specific way to do case-insensitive matching, you can do:

shopt -s nocasematch
[[ $LINUX_CONF = no ]] && echo linux

Or:

[[ ${LINUX_CONF,,} = no ]] && echo linux

(where ${VAR,,} is the syntax to convert a string to lower case).

You can also force a variable to be converted to lowercase upon assignment with:

typeset -l LINUX_CONF

That also comes from ksh and is also supported by bash and zsh.

More variants with other shells:

zsh

set -o  nocasematch
[[ $LINUX_CONF = no ]] && echo linux

(same as in bash).

setopt extendedglob
[[ $LINUX_CONF = (#i)no ]] && echo linux

(less dangerous than making all matches case insensitive)

[[ ${(L)LINUX_CONF} = no ]] && echo linux

(convert to lowercase operator)

set -o rematchpcre
[[ $LINUX_CONF =~ '^(?i)no\z' ]]

(PCRE syntax)

ksh93

[[ $LINUX_CONF = ~(i)no ]]

or

[[ $LINUX_CONF = ~(i:no) ]]

Note that all approaches above other than [nN][oO] to do case insensitive matching depend on the user's locale. Not all people around the world agree on what the uppercase version of a given letter is, even for ASCII ones.

In practice for the ASCII ones, at least on GNU systems, the deviations from the English rules seem to be limited to the i and I letters and whether the dot is there or not on the uppercase or lowercase version.

What that means is that [[ ${VAR,,} = oui ]] is not guaranteed to match on OUI in every locale (even when the bug in current versions of bash is fixed).


Keep your existing command but on the line before it run this:

LINUX_CONF=$(echo $LINUX_CONF | awk '{ print tolower($0) }')

Regardless of the case of the value stored in your variable this will force the replacement value to be lowercase. This results in matching your existing command with only one additional line of code.