बैश में, मैं एक यूनिकोड कोडपॉइंट [0-9A-F] को प्रिंट करने योग्य चरित्र में कैसे बदल सकता हूं?


23

मेरे पास यूनिकोड कोडपॉइंट्स की एक सूची है, लेकिन मुझे इन हेक्स मानों को वास्तविक वर्णों में बदलने के लिए "सरल" तरीके का पता नहीं है जो मैं प्रतिनिधित्व करता हूं ...

मैंने सुना है कि zsh है echo -e '\u0965', लेकिन मैं का उपयोग बैश 4.1।

क्या बाश के लिए zsh विधि के रूप में कुछ सरल है?


जवाबों:


16

आप आइकन के साथ संयोजन में GNU कोर्यूटिल्स से बैश की गूंज या / बिन / गूंज का उपयोग कर सकते हैं:

echo -ne '\x09\x65' | iconv -f utf-16be

डिफ़ॉल्ट रूप से iconv आपके स्थान एन्कोडिंग में कनवर्ट करता है। शायद एक विशिष्ट शेल या इको कमांड पर निर्भर होने से अधिक पोर्टेबल है पर्ल। अधिकांश UNIX प्रणाली, जिनके बारे में मुझे पता है, जबकि पर्ल उपलब्ध हैं और इसमें कई विंडोज पोर्ट भी हैं।

perl -C -e 'print chr 0x0965'

अधिकांश समय जब मुझे ऐसा करने की आवश्यकता होती है, मैं Vim / GVim जैसे संपादक में हूं, जिसमें अंतर्निहित समर्थन है। इन्सर्ट मोड में, Ctrl-V हिट करें और उसके बाद चार हेक्स अक्षर टाइप करें। यदि आप U + FFFF से परे एक चरित्र चाहते हैं, तो एक राजधानी U का उपयोग करें और 8 हेक्स वर्ण टाइप करें। विम भी keymaps बनाने के लिए कस्टम आसान का समर्थन करता है। यह पात्रों की एक श्रृंखला को दूसरे प्रतीक में परिवर्तित करता है। उदाहरण के लिए, मेरे पास एक कीमैप है जिसे मैंने www नाम से विकसित किया है, यह TM को ™, (C) को ©, (R) को®, और इसी तरह से रूपांतरित करता है। मेरे पास क्लिंगन के लिए एक कीमैप है जब वह आवश्यक हो जाता है। मुझे यकीन है कि Emacs में भी कुछ ऐसा ही है। यदि आप GTK + ऐप में हैं जिसमें GVim और GNOME टर्मिनल शामिल हैं, तो आप यूनिकोड वर्ण बनाने के लिए 4-हेक्स वर्णों के बाद कंट्रोल-शिफ्ट-यू का प्रयास कर सकते हैं। मुझे यकीन है कि केडीई / क्यूटी में भी कुछ ऐसा ही है।

अद्यतन: बैश 4.2 के रूप में, यह अब एक फीचर में बनाया गया लगता है:

echo $'\u0965'

अद्यतन: इसके अलावा, आजकल पायथन उदाहरण शायद पर्ल के लिए पसंद किया जाएगा। यह पायथन 2 और 3 दोनों में काम करता है:

python -c 'print(u"\u0965")'

धन्यवाद ... पर्ल एक अच्छा और कविता में, लेकिन यह मुझे थोड़ा हैरान है कि यह UTF-16BE के रूप में मूल्य को कैसे जानता है .. मुझे लगता है कि "chr" का अर्थ है ...
पीटर ओ

@ अगर यह एक अच्छा बिंदु है। पर्ल का उदाहरण स्थानीय संवेदनशील है। -C पूर्ण यूनिकोड प्रसंस्करण को सक्षम करता है, लेकिन उदाहरण काम करता है क्योंकि मेरा स्थान एक यूनिकोड उदाहरण का उपयोग करता है। यदि मैं LANG को C पर सेट करता हूं, तो मुझे प्रिंट में एक विस्तृत चरित्र के बारे में चेतावनी मिलती है, लेकिन यह अभी भी प्रिंट करता है। अगर मैं chr 0xa2UTF-8 लोकेल में प्रिंट करता हूं तो मुझे सेंट साइन मिलता है UT, लेकिन अगर मैं LANG = C का उपयोग करता हूं, तो मुझे UT मिलता है क्योंकि यह बाइट 0xa2 को प्रिंट करता है जो UTF-8 में अमान्य है। Vim / GVim उदाहरण स्थानीय के प्रति अर्ध-संवेदनशील है। अधिक सही ढंग से, फ़ाइल एन्कोडिंग के लिए। यदि आपने गैर-यूटीएफ -8 लोकेल में विम शुरू किया है, तो आपको:set encoding=utf-8
p41in359

@ अगर मुझे इंगित करना चाहिए, तो पर्ल ने यूनिकोड कोडपॉइंट के रूप में chr के मूल्य को माना है यदि पर्ल को यूटीएफ -8 जैसे यूनिकोड लोकल में शुरू किया गया है। एक कोडपॉइंट एक अद्वितीय संख्या है जो एक वर्ण का प्रतिनिधित्व करता है और किसी भी एक एन्कोडिंग जैसे UTF-16BE या UTF-8 से बंधा नहीं है। जब यह इसे प्रिंट करता है तो यह इसे सही एन्कोडिंग में बदल देता है। उदाहरण के लिए, क्यूनिफॉर्म साइन ए कोड कोड यू + 012000 है। मैं chr 0x12000इसका प्रतिनिधित्व करने के लिए पर्ल (यूनिकोड सक्रिय है) का उपयोग कर सकता हूं । UTF-16BE में, यह 0xd8, 0x08, 0xdc और 0x00 है। आप वर्ण U + 0965 है जो बस यूटीएफ -16 में 0x65 के बाद 0x09 बाइट्स होता है।
पेंग्विन 359

@ penguin359 .. धन्यवाद, एक दिन (उम्मीद है) मैं पर्ल पर एक अच्छी नज़र डालूंगा .. यह अथाह गूढ़ लगता है, लेकिन फिर शुरुआत में sed और regex किया, और अब यह काफी आसान है ... शायद यह थोड़ा सा है विम की तरह; एक कठिन सीखने की अवस्था, फिर सादे नौकायन .... यह आपकी व्याख्या को पढ़ने के लिए अच्छा है ... यह मार्ग प्रशस्त करता है ..
पीटर।

मैंने अभी (पुनः) पता लगाया है कि स्टीवन डी का प्रिंटफ सोलिटक्शन यूनिकोड रेंज के एएससीआईआई ब्लॉक को संभाल नहीं पाएगा, इसलिए आपका perlजवाब अब सबसे अच्छा है (मेरी विशेष आवश्यकताओं के लिए) .. मैंने पहले प्रिंटफ (महीने पहले) से इनकार कर दिया था , लेकिन मैं इसके बारे में भूल गया था। यहाँ इसकी सीमा के बारे में उत्तर / उत्तर दिया गया है ... क्यों Printf सभी पर एक त्रुटि की रिपोर्ट करता है, लेकिन तीन (ASCII- श्रेणी) यूनिकोड कोड पॉइंट्स
पीटर

13

बैश 4.2 (2011 में जारी) के लिए जोड़ा समर्थन echo -e '\u0965', printf '\u0965', printf %b '\u0965'और echo $'\u0965'भी काम करते हैं।

http://tiswww.case.edu/php/chet/bash/FAQ :

o   $'...', echo, and printf understand \uXXXX and \UXXXXXXXX escape sequences.

धन्यवाद ... मैं अभी भी मुख्य रूप से Ubuntu 10.04 में bash 4.1.5 का उपयोग कर रहा हूं, लेकिन यह जानना निश्चित रूप से अच्छा है कि यह अब 4.2 में उपलब्ध है। (+1)
पीटर

1
+1; ध्यान दें कि bash 4.2.xसंस्करण एक बग है जहां के बीच मूल्यों 0x80और 0xff( 128 - 255) - यानी, एक्स्टेंडेड ASCII रेंज में - सही ढंग से UTF8 एन्कोड और इसके बजाय सिर्फ के माध्यम से पारित कर दिया, गलत UTF8 चार में जिसके परिणामस्वरूप है कि कुछ टर्मिनलों के रूप में प्रस्तुत करना नहीं हैं ?। जैसा कि (कम से कम) 4.3.11यह तय किया गया है; यदि echo $'\ued'रेंडर करता है í, तो बग मौजूद नहीं है
mklement0

5

यदि आपके पास GNU कोरुटिल्स हैं, तो कोशिश करें printf:

$ printf '\u0965\n'

echo यदि आपका कंसोल UTF-8 का उपयोग कर रहा है और आप UTF-8 एन्कोडिंग का उपयोग कर सकते हैं:

$ echo -e '\xE0\xA5\xA5'

आप यूटीएफ -8 हेक्स एनकोडिंग की यूनिकोड की एक तालिका यहां पा सकते हैं: http://www.utf8-chartable.de/ । आप कई स्क्रिप्टिंग भाषाओं का उपयोग करके यूनिकोड कोड बिंदुओं को हेक्स में बदल सकते हैं। यहाँ अजगर का उपयोग करके एक उदाहरण दिया गया है:

python -c "print(unichr(int('0965', 16)).encode('utf-8').encode('hex'))"

निम्नलिखित एक पर्ल स्क्रिप्ट है जो तर्कों को सही हेक्स मान (यहाँ कई अनावश्यक कोष्ठक में बदल देगी):

#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use Encode;

foreach (@ARGV) {
    say unpack('H*', encode('utf8', chr(hex($_))))
}

उदाहरण के लिए,

./uni2utf 0965
e0a5a5

बेशक, अगर आपके पास पर्ल या पायथन है, तो आप पात्रों को प्रिंट करने के लिए भी इस्तेमाल कर सकते हैं।


धन्यवाद .. echoमैं क्या नहीं चाहता कि कोडपॉइंट्स 2-बाइट UTF-16 बिग-एंडियन हैं .. लेकिन आपने मुझे याद दिलाया है कि 2 प्रिंटफ फ़ंक्शन हैं! (मुझे लगा कि प्रिंटफ यह कर सकता है, और ऐसा लगता है कि मैं गलत को लागू करना चाहता हूं) ... $(which printf)काम करता है ... अजगर उदाहरण के लिए धन्यवाद .. लेकिन इसके लिए (मेरी सीखने की अवस्था), मैं करीब के रूप में छड़ी करने की कोशिश कर रहा हूं संभव के रूप में "कोसने" के रूप में संभव है कि केवल भाषा ही शामिल है .. (जब मैं बैश के साथ पर्याप्त आराम कर रहा हूँ, मैं पायथन में फंस जाऊंगा ... btw, .encode('hex')मुझे जो चाहिए उससे परे एक कदम है .. (मुझे लगा कि यह देखा गया) वहाँ थोड़ा व्यस्त है :)
पीटर।

हाँ, .encode ('हेक्स') सिर्फ हेक्स कोड प्राप्त करने के लिए था जो मेरे लिए गूंज के साथ काम करता था। खुशी है कि इसका कम से कम हिस्सा मददगार था।
स्टीवन डी

मैंने अभी-अभी आपको पर्ल स्निपेट देखा है .. धन्यवाद ... इन विभिन्न समाधानों को शामिल करना अच्छा है ... प्रिंटफ बिल्कुल वही है जो मैं देख रहा था (एक कमांड के अनुसार, उदाहरण के लिए) ... .. मैं एक अच्छी तरह से अपनी उपयोग न करने वाली अन्य-स्क्रिप्टिंग-भाषा पद्धति पोस्ट कर सकता हूं, जो हेक्स डेटा (कोई \ u, आदि) की एक धारा पर काम करता है ..
पीटर.ओआर

मैं विशेष रूप से printfऊपर की संक्षिप्तता को पसंद करता हूं , लेकिन यह `` u00A0 ... I've just re-discovered something I already knew (but dropped off the radar)... Here is a Question I asked about 4 months ago; [Why does printf report an error on all but three (ASCII-range) Unicode Codepoints](http://askubuntu.com/questions/20806/why-does-printf-report-an-error-on-all-but-three-ascii-range-unicode-codepoints)... So *penguin359's* perl` समाधान के नीचे मानों को संभालता नहीं है अब बहुत अच्छा लग रहा है :) .. यह एक एकल इनवोकटन है, और मैं "टाइप करने के लिए आसान" के बाद, इसलिए मैं दे दूँगा। उसके लिए ग्रीन-टिकperl
पीटर

2

अद्यतन: यहाँ एक एकल यूनिकोड मान को करने का एक तरीका है ... ("बैश" से मेरा मतलब है: किसी अन्य स्क्रिप्टिंग भाषा का उपयोग नहीं करना) .. इस आस्कुबंटु क्यू / ए में एक सुझाव के लिए गिल्स का धन्यवाद । इस लिंक के
अनुसार : recode (Obsoletes iconv, dos2unix, unix2dos) .. संपादित करें: लेकिन नीचे की टिप्पणी के अनुसार, "obsoletes 'का अर्थ" वैकल्पिक "हो सकता है

      echo -n 0x0965 |recode UTF-16BE/x4..UTF-8

यहाँ एक इनपुट के रूप में कच्चे हेक्स डंप को संसाधित करने की एक विधि है (अर्थात। कोई बच-उपसर्ग जैसे; \ u0965, और no \ x09 \ x65) ..
xxdएक हेक्स-डंप उपयोगिता (इसके साथ पैक vim-common) है जो एक कच्ची हेक्स डंप वापस कर सकती है। जिन पात्रों का डंप प्रतिनिधित्व करता है ... यूनिकोड कोडपॉइंट्स UTF-16BigEndian हैं, जो वास्तव में हेक्स-डंप है।
xxd रिवर्ट मोड में लाइन ब्रेक के साथ हेक्स मूल्यों की एक धारा को स्वीकार करता है। जिसे अनदेखा किया जाता है।

यह स्क्रिप्ट UTF-16BE स्ट्रीम बनाता है, जो तब मूल वर्णों में बदल जाती है।
अंतिम पंक्ति में दो आवश्यक कमांड होते हैं; xxdतथाiconv

for line in \
  "Matsuo Basho (1644-1694)" \
  "  pond" \
  "  frog jumps in" \
  "  plop!"
do 
  echo "$line" |iconv -f "$(locale charmap)" -t "UTF-16BE" |xxd -ps -u 
done |
#    (---this is the **revert** code---) 
tee >(xxd -p -u -r |iconv -f "UTF-16BE") ;echo

यहां आउटपुट (UTF-16BE हेक्स-डंप इनपुट दिखा रहा है, पहले)।
ध्यान दें; xxd60 हेक्स-अंकों पर एक न्यूलाइन के साथ अपने स्वयं के आउटपुट को सेगमेंट करता है ... रिवर्ट विकल्प इन न्यूलाइन्स को अनदेखा करता है .. यह किसी भी / सभी न्यूलाइन को अनदेखा करता है (जैसा कि हेक्स-अंक नहीं हैं) ।।

004D0061007400730075006F00200042006100730068006F002000280031
003600340034002D00310036003900340029000A
002000200070006F006E0064000A
0020002000660072006F00670020006A0075006D0070007300200069006E
000A
002000200070006C006F00700021000A

Matsuo Basho (1644-1694)
  pond
  frog jumps in
  plop!

चूँकि ऐसा लगता है कि आपने अपने उत्तर में p पेंगुइनin359 की जानकारी का उपयोग किया है, इसलिए आप उसके उत्तर को मेरे बजाय सही मान सकते हैं।
स्टीवन डी

@Steven D: एक उल्लेखनीय टिप्पणी, लेकिन "लगता है" ऑपरेटिव शब्द है। मैं अब कुछ दिनों के लिए इस तरह iconv का उपयोग कर रहा हूं, जो मुझे आश्चर्य हो रहा है कि क्या कोई एकल कमांड है। मैंने विंडोज़ (C ++) में इसी तरह की पूरी-फ़ाइल प्रोसेसिंग की है, इसलिए मुझे यूनिकोड की एक कारण समझ है। मैं वास्तव में एक त्वरित और सरल bashविधि के बाद था । "बैश" से मेरा मतलब है: बैश स्क्रिप्टिंग भाषा का उपयोग करना; पाइट नहीं / बैश के भीतर से पर्ल)। मैंने इसे एक उत्तर के रूप में जोड़ा है क्योंकि यह इस पृष्ठ को पढ़ने वाले किसी व्यक्ति के लिए कुछ मूल्य का हो सकता है। यह पूरी फाइल के लिए अच्छा वन-लाइनर है। printfमेरे लिए तुम्हारा सबसे अच्छा जवाब है।
पीटर।

2
मैं यह नहीं कहूंगा कि ऑस्कोलेट्स आइकनव को रिकोड करना, वास्तव में रिकोड आइकॉन की तुलना में पुराना है, और इन दिनों आइकनव को रिकोड की तुलना में डिफ़ॉल्ट रूप से अधिक सामान्यतः इंस्टॉल किया जाता है (उदाहरण के लिए, लिनक्स पर, आईकॉव लगभग हमेशा इंस्टॉल होता है क्योंकि यह libc के साथ आता है)।
गिलेस एसओ- बुराई को रोकना '

धन्यवाद .. मैं इस बारे में सोच रहा था .. कि वेब पेज बिल्कुल निश्चित संदर्भ नहीं है ... इसलिए यह एक विकल्प से अधिक है ...
पीटर

1

अपने OS के लिए डिफ़ॉल्ट एन्कोडिंग मानकर UTF-8 (अधिकांश वर्तमान डिस्ट्रोस के लिए सही है) तो आप किसी भी UNICODE कोड बिंदु को बदलने के लिए सीधे bash का उपयोग कर सकते हैं:

echo -e "Unicode Character 'DEVANAGARI DOUBLE DANDA' (U+0965) \U0965"

बेशक, ग्लिफ़ सही ढंग से तभी दिखाई देगा जब आपके पास सही फ़ॉन्ट होगा। बश 4.3 के रूप में सभी कोड बिंदु सही ढंग से काम करेंगे। और यह दो निर्मित विकल्प भी काम करेंगे:

printf "%b" "Unicode Character (U+0965) \U0965 \n"
echo $'Unicode Character (U+0965) \U0965'

ध्यान दें कि बैश 4.2 से यूनिकोड कोड अंक 0x80के लिए 0xFFगलत तरीके से एन्कोड किया है (बैश बग)। इस समस्या को हल करने के लिए आपको इस साइट पर प्रोग्राम पर एक नज़र रखना चाहिए (संख्याओं को चार्ट में परिवर्तित करने के मुद्दे पर गहन नज़र के लिए भी अच्छा है।


बाश 4.3 और zsh में मेरे लिए काम करता है। क्या बैश 4.2 के लिए एक बग रिपोर्ट है जिससे आप लिंक कर सकते हैं?
मिकेल

यह मुझे सही बग की तरह दिखता है: https://lists.gnu.org/archive/html/bug-bash/2012-02/msg00035.htmlविवरण: \ u और \ U गलत तरीके से मानों को \ u80 और \ uff के बीच सांकेतिक शब्दों में बदलना

0

बैश संस्करण 4.2 (और उच्चतर) में पैटर्न प्रतिस्थापन का उपयोग करना:

${parameter/pattern/string}

जैसा कि यहां बताया गया है http://steve-parker.org/sh/tips/pattern-substeration/

UNICODE_HEX="U+02211"
printf ${UNICODE_HEX/U+/"\U"}


UNICODE_HEX="U+03BB"
printf ${UNICODE_HEX/U+/"\U"}
λ         

1
ध्यान दें, जैसा कि पिछले उत्तर में बताया गया है , यह केवल bash संस्करण 4.2 (और उच्चतर) में काम करता है। वास्तव में, यह पहले वाले उत्तर में काफी कम जोड़ता है।
जी-मैन ने
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.