การพิมพ์ทศนิยมให้เป็นอักขระ ASCII คำสั่งของฉันจะไม่แสดงผลตามที่ต้องการ


14

ฉันต้องการที่จะส่งออกสตริงของตัวละคร ASCII ทั้งหมดด้วยคำสั่งดังต่อไปนี้

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

ผลลัพธ์ของคำสั่งข้างต้นคือ:

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

เป็นตัวเลขตัวแรก (จากซ้าย) ของแต่ละหมายเลข

เมื่อมองผ่านเว็บไซต์นี้ฉันได้พบกับคำตอบสำหรับปัญหาของฉันวิธีพิมพ์ตัวอักษร ASCII ที่พิมพ์ได้ทั้งหมดใน CLI? อย่างไรก็ตามฉันยังไม่เข้าใจว่าเพราะเหตุใดข้อมูลโค้ดต้นฉบับของฉันจึงไม่ส่งออกอักขระ ASCII ตามที่ต้องการ


1
POSIXบอกเรื่องนี้นี่เป็นcomp.unix.shellกระทู้ว่าทำไมมันเป็นสิ่งที่ถูกต้อง;)
sr_

@sr_ ขอบคุณที่ให้ความสำคัญกับกระทู้ มีคำอธิบายที่ฉันกำลังมองหา
Ifthikhan

คำตอบ:


13

คุณไม่สามารถพิมพ์รหัส ASCII โดยตรงโดยใช้สิ่งที่printf "%c" $iคล้ายกันใน C

คุณต้องแปลงค่าทศนิยมของ i เป็นค่าฐานแปดของมันก่อนแล้วจึงต้องพิมพ์โดยใช้printfและวาง\หน้าค่าฐานแปดตามลำดับ

ในการพิมพ์Aคุณจะต้องแปลงทศนิยม 65 ให้เป็นฐานแปดเช่น 101 และจากนั้นคุณต้องพิมพ์ค่าฐานแปดเป็น:

printf "\101\n"

สิ่งนี้จะพิมพ์ Aนี้จะพิมพ์

ดังนั้นคุณต้องแก้ไขเป็น:

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

แต่ด้วยการใช้awkคุณสามารถพิมพ์ได้เหมือนในภาษา C โดยตรง

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

7
ในbashและนี้สามารถทำได้โดยไม่ต้องห่วงและไม่มีคำสั่งภายนอก:zsh printf $(printf '\%o' {32..127})
จัดการ

@ การผลิต: ใช่แน่นอน .. ขอบคุณมากสำหรับการชี้มันออกมา ..
pradeepchhetri

1
@pradeepchhetri: ขอบคุณสำหรับการตอบสนองอย่างละเอียดและดูเหมือนว่าจะครอบคลุมรายละเอียดที่จำเป็นส่วนใหญ่ (ดังนั้นฉันเลือกคำตอบของคุณ) แต่ผมคิดว่ามันพลาดออกเป็นชิ้นสำคัญของข้อมูลซึ่งสามารถพบได้ในข้อความต่อไปนี้ที่unix.derkeiler.com/Newsgroups/comp.unix.shell/2007-07/... มันกล่าวว่า "ตัวถูกดำเนินการโต้แย้งจะถือว่าเป็นสตริงถ้าตัวระบุการแปลงที่สอดคล้องกันคือ b, c หรือ s ... "
Ifthikhan

ไม่ใช่(char)(127)Backspace หรืออะไรทำนองนั้น ไม่ว่ามันจะเป็นอะไรมันปรากฏเป็นหนึ่งในกล่องฐานสิบหกหรืออะไรก็ตามที่พวกเขาถูกเรียก หากคุณต้องการเพียง "พิมพ์" (เช่นอ่านได้) เพียงไปที่ 126 นอกจากนี้ยังมีความคิดที่ดีกับฐานแปด นั่นเป็นเรื่องที่ฉลาด ฉันคิดในแง่เลขฐานสิบหก (เช่นprintf '\x%x; {32..126}... หรือ 127 ฉันเดาว่าเนื่องจากคุณทุกคนทำเช่นนั้นด้วย) แต่มันก็ไม่ได้ผล Octal ช่วยประหยัดทั้งวัน! :) สุดท้าย @Ifthikhan ฉันไม่แน่ใจว่าคุณหมายถึงอะไร awkมักใช้คำสั่งแบบ C และไม่มีการ%cใช้คำสั่งอื่น การใช้หมายเลขฐานแปดแตกต่างจากการใช้อักขระหนึ่งไบต์
Dylan

3

%c ตีความอาร์กิวเมนต์ที่เกี่ยวข้องเป็นอักขระ char เฉพาะอักขระตัวแรกของอาร์กิวเมนต์ที่ระบุ

ดูเหมือนว่าคุณจะมีวิธีพิมพ์อยู่แล้ว แต่นี่คือตัวแปรหนึ่งตัว

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

0

คุณต้องการprintfแต่เพียงครั้งเดียว; คุณสามารถแทนที่หนึ่งการใช้งานprintfโดยechoลำดับการหลบหนีที่ง่ายและมีประสิทธิภาพมากขึ้นรวมถึง Bash:

ด้วย hexagesimals:

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

ด้วย octals:

for i in `seq 32 127`; do
  echo -ne \\0$(printf %03o $i)
done
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.