मैं बैश में विभिन्न कोड बिंदुओं द्वारा ASCII वर्ण कैसे प्रिंट कर सकता हूं?


12

ASCII तालिका में 'J' वर्ण मौजूद है जिसमें विभिन्न अंक प्रणालियों में कोड बिंदु हैं:

Oct   Dec   Hex   Char
112   74    4A    J

इस चार को एक ऑक्टल कोड बिंदु द्वारा प्रिंट करके printf '\112'या प्रिंट करके संभव है echo $'\112'। मैं दशमलव और हेक्साडेसिमल कोड बिंदु प्रस्तुतियों द्वारा एक ही चरित्र कैसे प्रिंट करूं?


जवाबों:



6

के साथ zsh:

$ printf '\x4a\n' # Hex
J
$ printf "\\$(([##8]74))\n" # Dec
J

यूनिकोड कोड बिंदु से एक वर्ण (वर्तमान वर्ण में) प्राप्त करने के लिए:

$ printf '\U1F42E\n' # Hex
🐮
$ printf "\\U$(([##16]128046))\n" # Dec
🐮

जवाब भी कृपया इस चेहरे को 'f0 9f 90 ae' हेक्स कोड द्वारा कैसे प्रिंट करें
थ्रूवड


6

सामान्य तौर पर, शेल चर में हेक्स, ऑक्ट और दशमलव संख्या को समझ सकता है, बशर्ते कि उन्हें इस प्रकार परिभाषित किया गया हो integers:

$ declare -i v1 v2 v3 v4 v5 v6 v7
$ v1=0112
$ v2=74
$ v3=0x4a
$ v4=8#112
$ v5=10#74
$ v6=16#4a
$ v7=18#gg
echo "$v1 $v2 $v3 $v4 $v5 $v6 $v7"
74 74 74 74 74 74 304

या वे "अंकगणित विस्तार" के परिणाम हैं:

$ : $(( v1=0112, v2=74, v3=0x4a, v4=8#112, v5=10#74, v6=16#4a, v7=18#gg ))
$ echo "$v1 $v2 $v3 $v4 $v5 $v6 $v7"
74 74 74 74 74 74 304

तो, आपको केवल उस वर्ण को प्रिंट करने के लिए एक तरीके की आवश्यकता है जो एक चर मान से संबंधित है।
लेकिन यहाँ दो संभावित तरीके हैं:

$ var=$((0x65))
$ printf '%b\n' "\\$(printf '0%o' "$var")"
e

$ declare -i var
$ var=0x65; printf '%b\n' "\U$(printf '%08x' "$var")"
e

दो प्रिंट की जरूरत है, एक मूल्य को हेक्साडेसिमल स्ट्रिंग में बदलने के लिए और दूसरा वास्तव में चरित्र को प्रिंट करने के लिए।

दूसरा कोई भी UNICODE बिंदु प्रिंट करेगा (यदि आपका कंसोल सही ढंग से सेट है)।
उदाहरण के लिए:

$ var=0x2603; printf '%b\n' "\U$(printf '%08x' "$var")"

एक हिम मानव।

वह चरित्र जिसमें एक utf-8 प्रतिनिधित्व है जैसा कि f0 9f 90 aeहै 0x1F42E। के लिए खोज cow face site:fileformat.infoकरने के लिए इसे पाने के :

$ var=0x1F42F; printf '%b\n' "\U$(printf '%08x' "$var")"
🐮

नोट : 4.3 से पहले बैश के लिए UNICODE के साथ एक समस्या है (उस संस्करण में और ऊपर की तरफ सही), UNICODE अंक 128 और 255 (दशमलव में) के बीच के अक्षर गलत तरीके से मुद्रित हो सकते हैं।


संदर्भ

चौथे पैरा के अंदर PARAMETERSमें man bash:

यदि चर का पूर्णांक विशेषता सेट है, तो मान का मूल्यांकन एक अंकगणितीय अभिव्यक्ति के रूप में किया जाता है, भले ही $ ((...)) विस्तार का उपयोग नहीं किया गया हो (नीचे अंकगणित विस्तार देखें)।

अंदर "कृत्रिम विकास" man bash:

एक अग्रणी 0 के साथ स्थिरांक को अष्टक संख्या के रूप में व्याख्या की जाती है। एक प्रमुख 0x या 0X हेक्साडेसिमल को दर्शाता है। अन्यथा, संख्याएं फार्म [आधार #] n लेती हैं, जहां वैकल्पिक आधार 2 और 64 के बीच एक दशमलव संख्या है जो अंकगणितीय आधार का प्रतिनिधित्व करता है, और n उस आधार में एक संख्या है। यदि आधार # छोड़ा गया है, तो आधार 10 का उपयोग किया जाता है। 9 से अधिक अंकों को उस क्रम में निचले अक्षरों, बड़े अक्षरों, @, और _ द्वारा दर्शाया जाता है। यदि आधार 36 से कम या इसके बराबर है, तो 10 और 35 के बीच संख्याओं का प्रतिनिधित्व करने के लिए लोअरकेस और अपरकेस अक्षरों का परस्पर विनिमय किया जा सकता है।


@ स्टीफनचैलेजेलस, एक कोडपॉइंट (हमेशा) एक बाइट मान नहीं है। बैश (4.3 से पहले के संस्करणों में) कोड बिंदु के बाइट मूल्य प्रदान करता है। वह है: चरित्र é(अष्टक: 351, दिसंबर: 233, हेक्स: 0xE9) गलत तरीके से मुद्रित होता है printf '\351'क्योंकि यह 0xE9हमेशा के बाइट मूल्य को प्रिंट करता है । ISO-8859-1(और चचेरे भाई) के एन्कोडिंग वाले एक टर्मिनल के लिए, जो काम कर सकता है, लेकिन utf-8 एन्कोडेड टर्मिनलों में, बाइट का मान 0xE9encoding के रूप में दिखाई देना चाहिए। cont ....
आइजैक

@ StéphaneChazelas मैं एक उदाहरण के लिए "बैश 4.2 गलत तरीके से एनकोड" के लिए नोटिस और खोज करने वाला पहला व्यक्ति नहीं हूं । इसे बैश 4.3 और उच्चतर से ठीक किया गया है।
इसहाक

ठीक। मैं देख रहा हूं कि अब आपका क्या मतलब है (मैं आपके उत्तर के पहले संस्करण के अनुसार 4.3 के साथ परीक्षण कर रहा था)। ध्यान दें कि यह केवल bash-4.2 है, bash-4.1 ने समर्थन नहीं किया \u(जो zsh से आता है)।
स्टीफन चेजलस



0

यदि आपके पास कनवर्ट करने के लिए संख्याओं की एक सूची है, और एक फ़ंक्शन कॉल से बचने और प्रत्येक वर्ण के लिए एक उपखंड बनाने से बचना चाहते हैं, तो आप पहले से निर्धारित एएससीआई को परिभाषित कर सकते हैं:

ascii=$(for x in {0..9} {A..F}; do for y in {0..9} {A..F}; do echo -ne "\x$x$y"; done; done)

ध्यान दें कि अशक्त चार को बाहर रखा गया है, इसलिए प्रत्येक वर्ण को 1 से ऑफसेट किया गया है।

तो कुछ इस तरह का उपयोग करें (प्रति पंक्ति 1 नंबर मान लेता है):

while read c; do out+="${ascii:$c-1:1}"; done <<< "$in"
echo "$out"

0

यहां सभी रूपांतरणों का उपयोग किया गया है printf:

printf "%o" "'J" # 112 (oct)
printf "%d" "'J" # 74 (dec)
printf "%x" "'J" # 4a (hex)

printf '\112' # J (oct)
printf "\x$(printf %x 74)" # J (dec, requires double conversion)
printf '\x4a' # J (hex)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.