Целочисленное значение ASCII для символа в BASH с использованием printf

85

Характер к значению работает:

$ printf "%d\n" \'A
65
$ 

У меня два вопроса, первый из них самый важный:

  • Как мне взять 65 и превратить его в А?
  • \ 'A преобразует символ ASCII в его значение с помощью printf. Является ли синтаксис специфичным для printf или он используется где-нибудь еще в BASH? (Такие маленькие строки трудно найти в Google.)

источник
В Windows используйте ALT + 65 для печати символа ASCII - к сожалению, это не сработает с Unix / bash;)
schnaader
2
@schnaader, но вы не можете это писать.
ctrl-alt-delor
2
@richard: Эээ ... это непросто и не практично, но можно :) "Просто" запустите виртуальную машину под управлением Windows или MS-DOS, отправьте "echo", ALT, 6, 5, "> mysharedfolder \ file.txt" как нажмите на него и прочитайте file.txt из общей папки виртуальной машины.
schnaader
2
@schnaader, ты можешь использовать вино для этого?
emory

Ответы:

70

Одна линия

printf "\x$(printf %x 65)"

Две строки

set $(printf %x 65)
printf "\x$1"

Вот один, если вы не против использовать awk

awk 'BEGIN{printf "%c", 65}'
расширять
источник
3
Должно сработатьprintf "$(printf '\\x%02x' $char)"
0andriy
31

Это работает (со значением в восьмеричном формате):

$ printf '%b' '\101'
A

даже для (некоторые: не превышайте 7) последовательностей:

$ printf '%b' '\'{101..107}
ABCDEFG

Общая конструкция, допускающая (десятичные) значения в любом диапазоне:

$ printf '%b' $(printf '\\%03o' {65..122})
ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz

Или вы можете использовать шестнадцатеричные значения символов:

$ printf '%b' $(printf '\\x%x' {65..122})
ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz

Вы также можете вернуть символ с помощью xxd (используйте шестнадцатеричные значения):

$ echo "41" | xxd -p -r
A

То есть одно действие противоположно другому:

$ printf "%x" "'A" | xxd -p -r
A

А также работает сразу с несколькими шестнадцатеричными значениями:

$ echo "41 42 43 44 45 46 47 48 49 4a" | xxd -p -r
ABCDEFGHIJ

или последовательности (здесь для получения шестнадцатеричных значений используется printf):

$ printf '%x' {65..90} | xxd -r -p 
ABCDEFGHIJKLMNOPQRSTUVWXYZ

Или даже используйте awk:

$ echo 65 | awk '{printf("%c",$1)}'
A

даже для последовательностей:

$ seq 65 90 | awk '{printf("%c",$1)}'
ABCDEFGHIJKLMNOPQRSTUVWXYZ

источник
14

Что касается вашего второго вопроса, похоже, что синтаксис ведущих кавычек ( \'A) специфичен для printf:

Если ведущий символ - это одинарная или двойная кавычка, значение должно быть числовым значением в базовом кодовом наборе символа, следующего за одинарной или двойной кавычкой.

С http://pubs.opengroup.org/onlinepubs/009695399/utilities/printf.html

Дэвид Ху
источник
9

Один из вариантов - напрямую ввести интересующий вас символ, используя шестнадцатеричную или восьмеричную нотацию:

printf "\x41\n"
printf "\101\n"
Naaff
источник
8

Для такого преобразования я использую perl:

perl -e 'printf "%c\n", 65;'
Mouviciel
источник
2
или в Perl выведите chr (65), "\ n"; Хотя perl может быть хорошим выбором, если вы делаете много этого, использование printf оболочки для преобразования вашего числа во что-то, что может перейти в escape-последовательность \ 0, отлично работает. С юникодом сложнее, так как вам нужна \ u поддержка в файле printf.
Питер Кордес
К сожалению, Perl - это забытый язык. Лучше Python, который сейчас есть почти на каждой машине Linux. Кроме того, речь идет о Shell-Bash, а не о других платформах!
s3n0 09
7

Если вы хотите сохранить значение ASCII символа: (я сделал это в BASH, и это сработало)

{
char="A"

testing=$( printf "%d" "'${char}" )

echo $testing}

выход: 65

МагияМеркурий86
источник
Это сработало, спасибо. Я хотел получить целое число (код ASCII) из типизированного символа. Я сделал скрипт: {read -n 1 c; echo $ (printf "% d" "'$ {c}")}
Федрус
4

Если вы конвертируете 65в шестнадцатеричный, это 0x41:

$ echo -e "\x41" A

Кибер Оливейра
источник
если вы знаете шестнадцатеричное значение для печати символа ASCII$ printf "\x41"
katta
4

Для заглавных букв:

i=67
letters=({A..Z})
echo "${letters[$i-65]}"

Вывод:

C
Сайрус
источник
3

Вот еще один способ преобразовать 65 в A (через восьмеричное):

help printf  # in Bash
man bash | less -Ip '^[[:blank:]]*printf'

printf "%d\n" '"A'
printf "%d\n" "'A"

printf '%b\n' "$(printf '\%03o' 65)"

Для поиска в man bashдля \'использования (хотя бесполезные в данном случае):

man bash | less -Ip "\\\'"  # press <n> to go through the matches
чанд
источник
1

это напечатает все "печатаемые" символы вашей базовой настройки bash:

printf '%b\n' $(printf '\\%03o' {30..127})

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
AG6HQ
источник
0

Вот решение без Eval , ни $ () , ни ``:

ord () {
 local s
 printf -v s '\\%03o' $1
 printf "$s"
}

ord 65
Vouze
источник