How do I change the case (upper and lower case) of strings in my variable?
Solution 1
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
Solution 2
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).
Solution 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
Solution 4
sed -ne '/^[aA]$/!i\' -e failed -e 's//worked/p;q' </dev/tty
Related videos on Youtube
Zac
Updated on September 18, 2022Comments
-
Zac over 1 year
"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?
-
Admin over 9 yearsWhich shell? bash?
-
-
muru over 9 yearsAn extension of (2):
[[ "${test,,}" == "a" ]]
. -
Costas over 9 yearsAs
=~
is match operator you can use [[ Aa =~ "$test" ]]. And so if[[
(bash keyword) is used instead of posixtest
so[[ "$test" == [Aa] ]]
is acceptable too. -
Stéphane Chazelas over 9 yearsNote that
bash
's case conversion doesn't work in all locales. Seea=i LC_ALL=tr_TR.UTF-8 bash -c 'echo "${a^^}"'
which givesi
instead of the expectedİ
(notI
) likea=i LC_ALL=tr_TR.UTF-8 zsh -c 'echo "${(U)a}"'
-
PM 2Ring over 9 years@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. :( -
Stéphane Chazelas over 9 yearsIt's not only Turkish locales. I've just reported it as a bash bug.
-
Stéphane Chazelas over 9 yearsabout your
locale -k
, look atinfo libc 'The Elegant and Fast Way'
(especially about the additional symbols in langinfo.h). Those are non-portable, subject to change GNU extensions. -
Hauke Laging over 9 years@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. -
PM 2Ring over 9 years@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.