0

I have the following shell script

#! /bin/bash

echo -e "Enter any character: \c"
read value

case $value in
    [a-z] )
        echo You have entered a lower case alphabet;;
    [A-Z] )
        echo You have entered an upper case alphabet;;
    [0-9] )
        echo You have entered a number;;
    [?] )
        echo You have entered a special character;;
    [*] )
        echo Unknown value;;
esac

Here, when I enter a upper case letter like

K

I get the output

You have entered a lower case alphabet

How to correct it?

Sonevol
  • 295
  • 2
  • 4
  • 12
  • 2
    Possibly related: [Why does \[A-Z\] match lowercase letters in bash?](https://unix.stackexchange.com/questions/227070/why-does-a-z-match-lowercase-letters-in-bash) – steeldriver Jul 16 '17 at 23:44

2 Answers2

1

In conjunction with steeldriver's collation link, the solution is to use sets as defined in man tr.

Also, a good reference for [[ vs [ Wooledge, GLOBS and why the following code may still fail with only [

  1 #! /bin/bash
  2 
  3 echo -e "Enter any character: \c"
  4 read -rN 1 value
  5 echo
  6 
  7 case $value in
  8     [[:lower:]] )
  9         echo You have entered a lower case alphabet;;
 10     [[:upper:]] )
 11         echo You have entered an upper case alphabet;;
 12     [[:digit:]] )
 13         echo You have entered a number;;
 14     [?] )
 15         echo You have entered a special character;;
 16     [*] )
 17         echo Unknown value;;
 18 esac

From wooledge link above:

Ranges

Globs can specify a range or class of characters, using square brackets. This gives you the ability to match against a set of characters. For example:

[abcd] Matches a or b or c or d

[a-d] The same as above, if globasciiranges is set or your locale is C or POSIX. Otherwise, implementation-defined.

[!aeiouAEIOU] Matches any character except a, e, i, o, u and their uppercase counterparts

[[:alnum:]] Matches any alphanumeric character in the current locale (letter or number)

[[:space:]] Matches any whitespace character

[![:space:]] Matches any character that is not whitespace

[[:digit:]_.] Matches any digit, or _ or .

For info on globasciiranges : Bash Reference Manual

flerb
  • 933
  • 1
  • 10
  • 19
  • Rather than making matters this much complex, a simple terminal writing `LANG=C` is much better. And steeldriver's link explains why `LANG=C` will work – Sonevol Jul 17 '17 at 09:35
0

Here, you need to set LANG as C

In terminal type

LANG=C

The LANG environment variable indicates the language/locale and encoding, where C is the language setting

Sonevol
  • 295
  • 2
  • 4
  • 12
  • Note that setting `$LANG` won't help if `$LC_COLLATE` or `$LC_ALL` is otherwise set. `LC_ALL=C` would ensure the `C` locale is used. – Stéphane Chazelas Aug 07 '17 at 10:20
  • Note that with `LANG=C`/`LC_ALL=C`, it would fail to recognise `É` as an uppercase letter or `π` as a lowercase one for instance. See `[[:upper:]]`/`[[:lower:]]` for characters considered uppercase/lowercase in the current locale. – Stéphane Chazelas Aug 07 '17 at 10:25