1

Possible Duplicate:
converting string to lower case in bash shell scripting

For example:

 echo *****Language translator*****
 echo please choose the language
 for Chinese enter c
 for French enter f

In a simple way I want to be able to recognize both C and c for Chinese; and the same thing for f and F, recognized as French.

Is there a way to convert everything to lower case?

Here part of the code:

if [ $language == c ];
then
echo "Enter the word to translate:"
read word_to_translate

Community
  • 1
  • 1
cacosud
  • 33
  • 1
  • 1
  • 7

4 Answers4

11

You can use tr to switch the chars to lowercase/uppercase:

echo $language | tr '[A-Z]' '[a-z]'
Kevin
  • 53,822
  • 15
  • 101
  • 132
Mike Bockus
  • 2,079
  • 17
  • 23
4

You can use the following case-modifiers (from man bash):

${parameter^}      # Convert the first character in ${parameter} to uppercase
${parameter^^}     # Convert all characters in ${parameter} to uppercase
${parameter,}      # Convert the first character in ${parameter} to lowercase
${parameter,,}     # Convert all characters in ${parameter} to lowercase

So your code might look something like this:

# Read one character into $lang, with a nice prompt.
read -n 1 -p "Please enter c for Chinese, or f for French: " lang
if [ "${lang,,}" == "c" ]; then
  echo "Chinese"
elif [ "${lang,,}" == "f" ]; then
  echo "French"
else
  echo "I don't speak that language."
fi
Adam Liss
  • 47,594
  • 12
  • 108
  • 150
2

Modern versions of tr have support for POSIX character classes [:upper:] and [:lower:]

tr -s '[:upper:]'  '[:lower:]' < inputfile > outputfile

All of the character classes are here:

http://ss64.com/bash/tr.html
jim mcnamara
  • 16,005
  • 2
  • 34
  • 51
  • 2
    **Be careful with that '-s'** -- it means "squeeze repeated chars into one" -- so, if you do `echo "FOOZBALL" | tr -s '[:upper:]' '[:lower:]'` you'll end up with "fozbal". Which may not be what you wanted. (For some reason, this variation of the answer is all over the Internets.) – Tom Hundt Dec 27 '18 at 06:09
2

I'd probably use a case statement, though there are other ways to do it:

read language
case "$language" in
([cC]) echo 'Chinese';;
([fF]) echo 'French';;
(*)    echo 'Unrecognized language abbreviation';;
esac

You could make a canonical assignment in the case if you need the values outside the switch:

read language
case "$language" in
([cC]) lingua='zh_tw'; echo 'Chinese';;
([fF]) lingua='fr_fr'; echo 'French';;
(*)    echo 'Unrecognized language abbreviation';;
esac
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • I'd always seen a case written as, e.g., `c|C) echo 'Chinese';;` Learn something new on SO every day! – Adam Liss Feb 21 '12 at 03:23
  • 1
    @AdamLiss: that also works. The 'real' Bourne shell doesn't like the open parenthesis before the expression; the POSIX shell (and hence `bash` and `ksh`) allows, but does not require, the leading parenthesis, and I use it because it makes it easier to 'match parentheses' in `vim`. The square brackets are part of the shell globbing, of course. – Jonathan Leffler Feb 21 '12 at 03:45
  • How can I use this in a if statement? for example – cacosud Feb 21 '12 at 03:46
  • 1
    You can't - or don't. The `case` is analogous to a multi-way `if` statement in its own right. – Jonathan Leffler Feb 21 '12 at 03:56
  • Re-re-reading the man page, I see that bash has also evolved to support "falling through" from one case to the next, optionally requiring the next pattern to match before executing the corresponding commands. – Adam Liss Feb 21 '12 at 14:36
  • In other words, `case $a in B) echo foo; lang=x-foo;; esac` is analogous to `if [ "$a" = "B" ] ; then echo foo; lang=x-foo; fi` – tripleee Feb 21 '12 at 15:16