Character to value works:
$ printf "%d\n" \'A
65
$
I have two questions, the first one is most important:
For this kind of conversion, I use perl:
perl -e 'printf "%c\n", 65;'
One line
printf "\x$(printf %x 65)"
Two lines
set $(printf %x 65)
printf "\x$1"
Here is one if you do not mind using awk
awk 'BEGIN{printf "%c", 65}'
For your second question, it seems the leading-quote syntax (\'A
) is specific to printf
:
If the leading character is a single-quote or double-quote, the value shall be the numeric value in the underlying codeset of the character following the single-quote or double-quote.
From https://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html
this prints all the "printable" characters of your basic bash setup:
printf '%b\n' $(printf '\\%03o' {30..127})
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
Here's yet another way to convert 65 into A (via octal):
help printf # in Bash
man bash | less -Ip '^[[:blank:]]*printf'
printf "%d\n" '"A'
printf "%d\n" "'A"
printf '%b\n' "$(printf '\%03o' 65)"
To search in man bash
for \'
use (though futile in this case):
man bash | less -Ip "\\\'" # press <n> to go through the matches
If you convert 65
to hexadecimal it's 0x41
:
$ echo -e "\x41"
A
Here is a solution without eval nor $() nor `` :
ord () {
local s
printf -v s '\\%03o' $1
printf "$s"
}
ord 65
This works (with the value in octal):
$ printf '%b' '\101'
A
even for (some: don't go over 7) sequences:
$ printf '%b' '\'{101..107}
ABCDEFG
A general construct that allows (decimal) values in any range is:
$ printf '%b' $(printf '\\%03o' {65..122})
ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz
Or you could use the hex values of the characters:
$ printf '%b' $(printf '\\x%x' {65..122})
ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz
You also could get the character back with xxd (use hexadecimal values):
$ echo "41" | xxd -p -r
A
That is, one action is the reverse of the other:
$ printf "%x" "'A" | xxd -p -r
A
And also works with several hex values at once:
$ echo "41 42 43 44 45 46 47 48 49 4a" | xxd -p -r
ABCDEFGHIJ
or sequences (printf is used here to get hex values):
$ printf '%x' {65..90} | xxd -r -p
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Or even use awk:
$ echo 65 | awk '{printf("%c",$1)}'
A
even for sequences:
$ seq 65 90 | awk '{printf("%c",$1)}'
ABCDEFGHIJKLMNOPQRSTUVWXYZ
If you want to save the ASCII value of the character: (I did this in BASH and it worked)
{
char="A"
testing=$( printf "%d" "'${char}" )
echo $testing}
output: 65
For capital letters:
i=67
letters=({A..Z})
echo "${letters[$i-65]}"
Output:
C
One option is to directly input the character you're interested in using hex or octal notation:
printf "\x41\n"
printf "\101\n"
Source: Stackoverflow.com