Giá trị ASCII nguyên thành ký tự trong BASH sử dụng printf


84

Đặc điểm để đánh giá tác phẩm:

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

Tôi có hai câu hỏi, câu hỏi đầu tiên là quan trọng nhất:

  • Làm thế nào để tôi lấy 65 và biến nó thành A?
  • \ 'A chuyển đổi một ký tự ASCII thành giá trị của nó bằng cách sử dụng printf. Cú pháp dành riêng cho printf hay nó được sử dụng ở bất kỳ nơi nào khác trong BASH? (Những chuỗi nhỏ như vậy rất khó tìm được Google.)
bash  ascii  printf 

Trong Windows, sử dụng ALT + 65 để in ký tự ASCII - rất tiếc điều đó sẽ không hoạt động khi sử dụng Unix / bash;)
schnaader

2
@schnaader nhưng bạn không thể tập lệnh đó.
ctrl-alt-delor

2
@richard: Errr .. nó không dễ và cũng không thực tế, nhưng bạn có thể :) "Chỉ cần" khởi động một máy ảo chạy Windows hoặc MS-DOS, gửi "echo", ALT, 6, 5, "> mysharedfolder \ file.txt" dưới dạng nhấn phím vào nó và đọc file.txt từ thư mục chia sẻ VM.
schnaader

2
@schnaader bạn có thể sử dụng rượu vang để làm điều đó không?
emory

Câu trả lời:


69

Một đường thẳng

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

Hai dòng

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

Đây là một nếu bạn không ngại sử dụng awk

awk 'BEGIN{printf "%c", 65}'

3
Sẽ hoạt động tốtprintf "$(printf '\\x%02x' $char)"
0andriy

31

Điều này hoạt động (với giá trị bằng bát phân):

$ printf '%b' '\101'
A

ngay cả đối với (một số: không vượt quá 7) chuỗi:

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

Một cấu trúc chung cho phép các giá trị (thập phân) trong bất kỳ phạm vi nào là:

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

Hoặc bạn có thể sử dụng các giá trị hex của các ký tự:

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

Bạn cũng có thể lấy lại ký tự bằng xxd (sử dụng các giá trị thập lục phân):

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

Đó là, một hành động là mặt trái của hành động kia:

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

Và cũng hoạt động với nhiều giá trị hex cùng một lúc:

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

hoặc các chuỗi (printf được sử dụng ở đây để nhận các giá trị hex):

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

Hoặc thậm chí sử dụng awk:

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

ngay cả đối với các chuỗi:

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

14

Đối với câu hỏi thứ hai của bạn, có vẻ như cú pháp trích dẫn đầu ( \'A) dành riêng choprintf :

Nếu ký tự đứng đầu là một dấu ngoặc đơn hoặc dấu ngoặc kép, giá trị sẽ là giá trị số trong bộ mã cơ bản của ký tự theo sau dấu nháy đơn hoặc dấu nháy kép.

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


9

Một tùy chọn là nhập trực tiếp ký tự bạn muốn sử dụng ký hiệu hex hoặc bát phân:

printf "\x41\n"
printf "\101\n"

8

Đối với loại chuyển đổi này, tôi sử dụng perl:

perl -e 'printf "%c\n", 65;'

2
hoặc trong perl, print chr (65), "\ n"; Mặc dù perl có thể là một lựa chọn tốt nếu bạn đang thực hiện nhiều việc này, nhưng việc sử dụng printf của shell để chuyển đổi số của bạn thành một thứ có thể chuyển thành chuỗi thoát \ 0 hoạt động tốt. Phức tạp hơn với unicode, vì bạn cần \ u hỗ trợ trong printf của mình.
Peter Cordes

Thật không may, Perl là một ngôn ngữ bị lãng quên. Tốt hơn là Python, hiện có trong hầu hết mọi máy Linux. Ngoài ra, câu hỏi là về Shell-Bash chứ không phải các nền tảng khác!
s3n0 Ngày

7

Nếu bạn muốn lưu giá trị ASCII của ký tự: (Tôi đã làm điều này trong BASH và nó đã hoạt động)

{
char="A"

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

echo $testing}

sản lượng: 65


Điều này đã làm việc, cảm ơn. Tôi muốn lấy Số nguyên (mã ASCII) từ một ký tự đã nhập. Tôi đã tạo một tập lệnh: {read -n 1 c; echo $ (printf "% d" "'$ {c}")}
Phaedrus

4

Nếu bạn chuyển đổi 65sang hệ thập lục phân thì đó là 0x41:

$ echo -e "\x41" A


nếu bạn biết giá trị hex để in ký tự ASCII$ printf "\x41"
Katta

3

Đây là một cách khác để chuyển 65 thành A (thông qua hệ bát phân):

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

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

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

Để tìm kiếm man bashđể \'sử dụng (mặc dù vô ích trong trường hợp này):

man bash | less -Ip "\\\'"  # press <n> to go through the matches

3

Đối với chữ in hoa:

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

Đầu ra:

C

1

điều này sẽ in tất cả các ký tự "có thể in" của thiết lập cơ bản của bạn:

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

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.