I'm trying to write a shell script which asks for an ASCII character in the range A-Z or a-z and returns its equivalent numerical value. For example, the output might look like the following:

scarlet$ Please type a character between A and Z or between a and z:
scarlet$ A       
scarlet$ The decimal value of A is: 65 

My attempt:

echo Enter a letter:
read A
echo -n ${A} | od -i | head -1 | cut -b 10- | tr -d " "
  • I edited out your second question since it was unrelated; you should post it separately (you can get the original text here) – Michael Mrozek Mar 18 '11 at 2:19
  • Your example works for me. Can you paste output showing what happens and describe what the error is? Does echo -n A do what you expect? If not, try printf instead. Does od -i do what you expect? If not, try od -t d1. – Mikel Mar 18 '11 at 3:10
  • 1
    I tried od -t d1 worked great... Thanks – Host Post Mar 19 '11 at 12:11

POSIX: printf a | od -A n -t d1

Perl: perl -e 'print ord($ARGV[0])' a

Perl, coping with UTF-8 if in a UTF-8 locale: perl -C255 -e 'print ord($ARGV[0])' œ



$ printf %d\\n \'a

It also works with non-ASCII characters in bash 4.0 and later and in zsh:

$ printf %x\\n \'あ

You can also use recode ..dump to see hexadecimal code points:

$ printf aあ|recode ..dump
UCS2   Mne   Description

0061   a     latin small letter a
3042   a5    hiragana letter a
  • 2
    To make it a little bit less "obscure", one may also use e.g. A=a ; printf '%d\n' "'$A'" and on ksh something like A=a; integer N=$(("'$A'")); print $N (print or printf is not needed). – jelmd Nov 12 '17 at 17:03



echo -n "Enter a letter:"
read A
echo ${A}|od -t d1|awk '{printf "%s",$2}';echo


  • I would just use awk, rather than nawk. This is pretty standard to any awk version. – asoundmove Mar 18 '11 at 3:47
  • Edited, is my habit of using 'nawk' since i've not awk at work – D4RIO Mar 18 '11 at 11:36
  • yes, your solution worked for me too .. thanks – Host Post Mar 19 '11 at 12:14

A od-less solution, just bash, and just lowercase, so far. z is the character searched for, here s as search. i=97 because ascii(a)=97. The rest is obvious.

for c in {a..z}
    [ "$c" = "$z" ] && echo $i && break || ((i+=1))

You may put it into a single line of course. Here are some semmicolons: ;;;;; (should be enough)

  • I tested the above code .. but it didn't work for me .. I got a message saying " i+=1 " is not found! – Host Post Mar 19 '11 at 18:19
  • This works in bash. You may need i=$((i+1)) instead. – user unknown Mar 19 '11 at 18:49
  • In one line and with reading a key from the keyboard: read char; i=97; for c in {a..z}; do [ "$c" = "$char" ] && echo $i && break || ((i+=1)); done – erik Aug 30 '13 at 21:33

Try od -t d1 if you have it. The other output formats are quite weird.

You also don't need head and cut, for example:

printf "A" | od -t d1 | read addr num && echo $num

If you just want a program that does this and you're not doing this as an exercise then there's a program called ascii that does this. Your distro may offer it as a package already, if not get it from http://www.catb.org/~esr/ascii/.

# Get one character per loop, until the user presses <Enter>
while true ; do 
    read -n 1 c
    (( ${#c} == 0 )) && break # Exit the loop. Input length is 0  
                              # ie. The user has pressed Enter
    if [   \( ! "$c" \< "a" -a  ! "$c" \> "z" \) \
        -o \( ! "$c" \< "A" -a  ! "$c" \> "Z" \) ]
        val=($(ascii -s $c)) # build an array of ascii info for this char 
        echo " ... The decimal value of $c is: ${val[1]}"
        echo -n  $'\r \r' # overwrite the invalid character

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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