2
"Enter test: "
read test

if [[ $test == "a" ]]; then
    echo "worked"
else
    echo "failed"
fi

It's a simple illustration of test I'm doing, but if I enter "A", it will fail. Is there anything I can do at the variable stage to change it all to small case, so that the test will match?

1
  • 5
    Which shell? bash? Commented Jan 22, 2015 at 13:21

4 Answers 4

7

Just use the standard sh (POSIX and Bourne) syntax:

case $answer in
  a|A) echo OK;;
  *)   echo >&2 KO;;
esac

Or:

case $answer in
  [aA]) echo OK;;
  *)    echo >&2 KO;;
esac

With bash, ksh or zsh (the 3 shells that support that non-standard [[...]] syntax), you can declare a lower case variable:

typeset -l test
printf 'Enter test: '
read test
if [ "$test" = a ]; then...

(beware that bash's case conversion is bogus in some locales).

6

There are several useful ways to achieve this (in bash):

two checks

echo -n "Enter test: "
read test

if [[ $test == "a" || $test == "A" ]]; then
    echo "worked"
else
    echo "failed"
fi

make the input lower case

echo -n "Enter test: "
read test
test="${test,,}"

if [[ $test == "a" ]]; then
    echo "worked"
else
    echo "failed"
fi

regex for both cases

echo -n "Enter test: "
read test

if [[ $test =~ ^[aA]$ ]]; then
    echo "worked"
else
    echo "failed"
fi

make the shell ignore the case

echo -n "Enter test: "
read test

shopt -s nocasematch
if [[ $test == a ]]; then
    echo "worked"
else
    echo "failed"
fi
3
  • 2
    An extension of (2): [[ "${test,,}" == "a" ]].
    – muru
    Commented Jan 22, 2015 at 13:31
  • As =~ is match operator you can use [[ Aa =~ "$test" ]]. And so if [[ (bash keyword) is used instead of posix test so [[ "$test" == [Aa] ]] is acceptable too.
    – Costas
    Commented Jan 22, 2015 at 13:48
  • @Costas [[ Aa =~ "$test" ]] doesn't make sense. That matches even . as input. Even if the reversal of string and pattern may work sometimes that is certainly not a good idea. Commented Jan 22, 2015 at 15:09
3

There are several ways to do this. If you're using a recent version of bash it's quite easy: you can convert the case of test, or you can use a regex to match both upper & lower case a.

First the regex way:

read -p "enter test: " test;[[ $test =~ ^[Aa]$ ]] && echo yes || echo no

Now the case shifter:

read -p "enter test: " test;[[ ${test^^} = A ]] && echo yes || echo no
5
  • Note that bash's case conversion doesn't work in all locales. See a=i LC_ALL=tr_TR.UTF-8 bash -c 'echo "${a^^}"' which gives i instead of the expected İ (not I) like a=i LC_ALL=tr_TR.UTF-8 zsh -c 'echo "${(U)a}"' Commented Jan 22, 2015 at 14:02
  • @StéphaneChazelas: How annoying! Thanks for that info, Stéphane. Unfortunately, I can't test that example as I don't have that locale (Turkish?) on my system. FWIW, I don't know much about locales, but yesterday I was trying to find an equivalent in Python of locale -k LC_IDENTIFICATION ... to no avail. :(
    – PM 2Ring
    Commented Jan 22, 2015 at 14:08
  • It's not only Turkish locales. I've just reported it as a bash bug. Commented Jan 22, 2015 at 14:45
  • about your locale -k, look at info libc 'The Elegant and Fast Way' (especially about the additional symbols in langinfo.h). Those are non-portable, subject to change GNU extensions. Commented Jan 22, 2015 at 14:58
  • @StéphaneChazelas: I see. The file langinfo.h defines a lot more symbols but none of them is official. Using them is not portable, and the format of the return values might change. Therefore we recommended you not use them. No wonder Python doesn't give me access to that info. Oh well. I just wanted an equivalent of LANG="$name" locale -k LC_IDENTIFICATION | grep -E '^(title|language|territory|ident)' which is a handy way to verify that a locale refers to the language that you think it does. IMHO.
    – PM 2Ring
    Commented Jan 23, 2015 at 8:30
1
sed -ne '/^[aA]$/!i\' -e failed -e 's//worked/p;q' </dev/tty

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .