Mencetak desimal ke karakter ascii, perintah saya tidak menampilkan seperti yang dimaksudkan


14

Saya ingin menampilkan string semua karakter ascii dengan perintah berikut

for i in `seq 32 127`; do printf "%c" $i; done

Output dari perintah di atas adalah:

33333334444444444555555555566666666667777777777..............

Ini adalah digit pertama (dari kiri) dari setiap nomor.

Melihat melalui situs ini saya menemukan jawaban untuk masalah saya. Bagaimana cara mencetak semua karakter ASCII yang dapat dicetak di CLI? , namun saya masih tidak mengerti mengapa cuplikan asli saya tidak menampilkan karakter ascii sebagaimana dimaksud.


1
POSIX mendiktekan ini, inilah comp.unix.shellutas mengapa itu hal yang benar;)
sr_

@ sr_ Terima kasih telah menunjukkan utasnya. Itu penjelasan yang saya cari.
Ifthikhan

Jawaban:


13

Anda tidak dapat langsung mencetak kode ascii dengan menggunakan printf "%c" $isejenisnya di C.

Anda harus terlebih dahulu mengkonversi nilai desimal i menjadi nilai oktal dan kemudian Anda harus mencetaknya menggunakan printfdan meletakkan \di depan nilai oktal masing-masing.

Untuk mencetak A, Anda harus mengubah desimal 65 menjadi oktal, yaitu 101, dan kemudian Anda harus mencetak nilai oktal itu sebagai:

printf "\101\n"

Ini akan dicetak A.

Jadi, Anda harus memodifikasinya untuk:

for i in `seq 32 127`; do printf \\$(printf "%o" $i);done;

Tetapi dengan menggunakan awkAnda dapat langsung mencetak seperti dalam bahasa C.

awk 'BEGIN{for(i=32;i<=127;i++)printf "%c",i}';echo

7
Dalam bashdan zshini dapat dilakukan tanpa loop dan tanpa perintah eksternal: printf $(printf '\%o' {32..127}).
manatwork

@manatwork: ya persis..terima kasih banyak untuk menunjukkannya ..
pradeepchhetri

1
@pradeepchhetri: Terima kasih atas tanggapan terperinci dan sepertinya mencakup sebagian besar detail yang diperlukan (maka saya pilih jawaban Anda). Namun saya kira itu melewatkan bagian penting dari informasi yang dapat ditemukan dalam pesan berikut di unix.derkeiler.com/Newsgroups/comp.unix.shell/2007-07/… . Ini menyatakan bahwa "Operan argumen harus diperlakukan sebagai string jika specifier konversi yang sesuai adalah b, c, atau s ..."
Ifthikhan

Bukan (char)(127)backspace atau semacamnya. Apa pun itu, ia muncul sebagai salah satu kotak hex atau apa pun namanya. Jika Anda hanya menginginkan "printable" (yaitu dapat dibaca), langsung saja ke 126. Juga, pemikiran yang bagus dengan oktal. Itu pintar; Saya sedang berpikir dalam heksadesimal (seperti printf '\x%x; {32..126}... atau 127, saya kira, karena kalian semua juga melakukannya), tetapi itu tidak berhasil. Oktal menyelamatkan hari! :) Akhirnya, @Ifthikhan, saya tidak yakin apa yang Anda maksud. awksering menggunakan perintah C-style dan tidak ada tempat lain %cdigunakan. Menggunakan angka oktal berbeda dari menggunakan karakter satu byte.
Dylan

3

%c Menafsirkan argumen terkait sebagai karakter: hanya karakter pertama dari argumen yang diberikan yang dicetak

Anda sepertinya sudah memiliki cara untuk mencetaknya, tetapi di sini ada satu varian.

for i in `seq 32 127`; do printf "\x$(printf "%x" $i) $i"; done

0

Anda perlu printf, tetapi hanya sekali; Anda dapat mengganti satu penggunaan printfdengan echourutan Bash escape yang lebih sederhana dan lebih efisien :

Dengan hexagesimal:

for i in `seq 32 127`; do
  echo -ne \\x$(printf %02x $i)
done

Dengan oktal:

for i in `seq 32 127`; do
  echo -ne \\0$(printf %03o $i)
done
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.