How do I check if a variable is in [A-Z]?

I want to achieve something like this:

read var

while [ $var in [A-Z] ]
 #code here

How do I achieve this?

closed as unclear what you're asking by tripleee, don_crissti, Jeff Schaller, Stephen Rauch, GAD3R Jul 1 '17 at 14:59

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    Is $var a single character or do you want to test that it contains only letters? – terdon Sep 26 '13 at 16:44
  • And are you intending to loop over multiple inputs? – Jeff Schaller Jul 1 '17 at 12:19

In bash, you can use a pattern on the right hand side of a == in a [[ ... ]]:

read var
LC_ALL=C # Turn off locale.
if [[ $var == [A-Z] ]] ; then
    echo yes

Turning off locale might be needed if you do not want y to be in A-Z.


The simple one liner would be:

re='[a-zA-Z]'; if [[ Z =~ $re ]]; then echo "Match"; else echo "No match"; fi

The full script would be:


read -p "Enter a char or string > " var

if [[ "$var" =~ $re ]]; then
    echo "Entered string matches."
    echo "Entered string does not match";

Assuming $var is a single character:

I you used case then it would be portable to any sh shell:

case "$var" in [A-Z]) thing_to_do_here ;;

or even

case "$var" in [[:upper:]]) thing_to_do_here ;; esac

For those of you who do not like unbalanced parens: It's ok to write

case "$var" in ([[:upper:]]) thing_to_do_here ;; esac
  • This checks whether at least one character is in the range. I'd have guessed the OP wants all characters to match, perhaps only allowing single-character strings. – tripleee Jul 1 '17 at 10:25
  • You could do case $var in *[!A-Z]* | ??) exit 255;; esac to reject invalid strings (the second alternative rejects anything longer than a single character, take it out if you don't want that; and the exit might be too draconian). – tripleee Jul 1 '17 at 10:29
  • @tripleee That's a matter of interpretation of the question, related to terdon's query to the question itself. I'm assuming a single character. – Kusalananda Jul 1 '17 at 10:54
  • Then the wildcards around the condition are wrong. If other code forces the input to be a single character, it doesn't matter, but what the cooe actually does is to check that there is at least one matching character in a potentially longer string. – tripleee Jul 1 '17 at 10:58
  • @tripleee Almost a year since I wrote that answer. But I'll update it. – Kusalananda Jul 1 '17 at 11:00

If you don't want to rely on Bash's regular expressions:

remainder=$(tr -d A-Z <<<$var)
while [ ! -z $remainder ];do
    read -p "Invalid value entered. Please try again." var
    remainder=$(tr -d A-Z <<<$var)

I'm guessing you want to use this for input validation.


It's a bit late but you can use grep and do something like this:

read var
if grep -q "[a-z]" <<< "$var"

Not the answer you're looking for? Browse other questions tagged or ask your own question.