คุณสะท้อนอักขระ Unicode 4 หลักใน Bash ได้อย่างไร


224

ฉันต้องการเพิ่มกะโหลก Unicode และ crossbones ใน shell prompt ของฉัน (โดยเฉพาะ 'SKULL AND CROSSBONES' (U + 2620)) แต่ฉันไม่สามารถหาคาถาเวทมนต์เพื่อสะท้อนเสียงคายหรือสิ่งอื่นใด อักขระ Unicode 4 หลัก หนึ่งหลักสองหลักนั้นง่าย ตัวอย่างเช่น echo -e "\ x55",

นอกจากคำตอบด้านล่างนี้แล้วควรสังเกตว่าเทอร์มินัลของคุณต้องรองรับ Unicode เพื่อให้ได้ผลลัพธ์ตามที่คุณคาดหวัง gnome-terminal ทำงานได้ดีในเรื่องนี้ แต่ไม่จำเป็นต้องเปิดใช้งานตามค่าเริ่มต้น

ในแอป Terminal ของ macOS ไปที่การตั้งค่า -> การเข้ารหัสและเลือก Unicode (UTF-8)


7
โปรดทราบว่าความคิดเห็น"2 หลักของคุณนั้นง่าย (สำหรับเสียงก้อง)"ความคิดเห็นนั้นใช้ได้กับค่าสูงสุด "\x7F"ในโลแคล UTF-8 (ซึ่งbashแท็กแนะนำให้คุณทราบ) ... รูปแบบที่แทนด้วยไบต์เดียวจะไม่อยู่ในช่วง\x80-\xFF. ช่วงนี้ผิดกฎหมายในตัวอักษร UTF-8 แบบซิงก์ไบต์ เช่นค่า Unicode Codepoint ของU+0080(เช่น. \x80) จริง ๆ แล้วคือ 2 ไบต์ใน UTF-8 .. \xC2\x80..
Peter.O

4
printf "\\u007C\\u001C"เช่น
kenorb

หมายเหตุ:สำหรับฉันในgnome-terminal, echo -e '\ufc'ไม่ได้ผลิตüแม้จะมีการเข้ารหัสอักขระชุด UTF-8 อย่างไรก็ตามเช่นurxvtพิมพ์เช่นprintf "\\ub07C\\ub01C"ตามที่คาดไว้ (ไม่ได้มี หรือกล่อง)
isomorphismes

@ Peter.O เหตุใดbashแท็กจึงมีประโยชน์อย่างยิ่ง เทอร์มินัลต่าง ๆ นั้นพบได้ทั่วไปใน CJK หรือ ... ?
isomorphismes

1
@ Peter.O zsh, ปลา, scsh, elvish และอื่น ๆ ... มีเชลล์ที่แตกต่างกันจำนวนมากแต่ละตัวสามารถจัดการกับอักขระยูนิโค้ดได้อย่างไรก็ตามพวกเขาต้องการ (หรือไม่) "ทุบตี" ทำให้ชัดเจนว่าคำถามนี้ไม่ได้เกี่ยวกับเปลือกแปลก ๆ ที่ทำสิ่งที่แตกต่าง
masukomi

คำตอบ:


237

ใน UTF-8 เป็นจริง 6 หลัก (หรือ 3 ไบต์)

$ printf '\xE2\x98\xA0'

เพื่อตรวจสอบวิธีการเข้ารหัสโดยคอนโซลใช้ hexdump:

$ printf  | hexdump
0000000 98e2 00a0                              
0000003

5
ผลของฉัน " " แทนที่จะเป็น☠ ... ทำไมถึงเป็นเช่นนั้น
trusktr

8
นั่นเป็นเรื่องจริง ผมค้นพบฉันถูกใช้แทนLANG=C LANG=en_US.UTF-8ทีนี้เทอร์มินัลของฉันใน Gnome แสดงสัญลักษณ์อย่างถูกต้อง ... เทอร์มินัลจริง (tty1-6) ยังคงทำไม่ได้
trusktr

6
สำหรับคนผู้ที่พยายาม hexdump A: แปลว่า0000000 f0 9f 8d ba \xf0\x9f\x8d\xbaตัวอย่างเสียงสะท้อน: echo -e "\xf0\x9f\x8d\xba".
เบลส

8
นอกจากนี้คุณยังสามารถใช้$'...'ไวยากรณ์ที่จะได้รับตัวละครในการเข้ารหัสให้กับตัวแปรโดยไม่ต้องใช้$(...)subshell จับสำหรับการใช้งานในบริบทที่ไม่ได้ตัวเองตีความลำดับหนี:skull=$'\xE2\x98\xA0'
แอนดรู Janke

7
อีกสิ่งหนึ่งที่เกี่ยวกับ hexdump: 0000000 98e2 00a0ในเครื่องของฉันคำสั่งที่สองในผลคำตอบ แน่นอนว่า0000000มันเป็นเพียงอ็อฟเซ็ตที่ไม่สำคัญ แต่ไบต์หลังจากแปลเป็น\xe2\x98\xa0เพราะเครื่องใช้ลำดับไบต์ endian เล็กน้อย
sigalor

98
% echo -e '\u2620'     # \u takes four hexadecimal digits

% echo -e '\U0001f602' # \U takes eight hexadecimal digits
😂

ใช้งานได้ใน Zsh (ฉันได้ตรวจสอบเวอร์ชั่น 4.3) และใน Bash 4.2 หรือใหม่กว่าแล้ว


16
มันพ่นออกมา \ u2620 เมื่อฉันทำ
masukomi

ให้ฉันด้วย. คุณกำลังใช้เชลล์ตัวไหนจูเลียโน
Joachim Sauer

2
ขออภัยลืมที่จะบอกว่าฉันใช้ zsh
Juliano

32
เพิ่มการรองรับ \ u ใน Bash 4.2
Lri

4
ไม่ทำงานสำหรับฉัน Mac OS 10.14.2, bash (GNU bash, เวอร์ชัน 3.2.57 (1) - ปล่อย (x86_64-apple-darwin18) มันพิมพ์เฉพาะอินพุต - $ echo -e '\ u2620' <enter> เพียงพิมพ์ออกมา: \ u2620
Motti Shneor

68

ตราบใดที่เครื่องมือแก้ไขข้อความของคุณสามารถรับมือกับ Unicode (สันนิษฐานว่าเข้ารหัสใน UTF-8) คุณสามารถป้อน Unicode code-point ได้โดยตรง

ตัวอย่างเช่นในVim text-editor คุณจะเข้าสู่โหมดแทรกและกดCtrl+ V+ Uจากนั้นหมายเลขรหัสจุดเป็นตัวเลขฐานสิบหก 4 หลัก (pad พร้อมเลขศูนย์ถ้าจำเป็น) ดังนั้นคุณจะพิมพ์Ctrl+ +V U 2 6 2 0ดู: วิธีที่ง่ายที่สุดในการแทรกอักขระ Unicode ลงในเอกสารคืออะไร

ที่ทำงานสถานีทุบตีคุณจะพิมพ์CTRL+ SHIFT+ Uและประเภทในฐานสิบหกรหัสจุดของตัวละครที่คุณต้องการ uในระหว่างการป้อนข้อมูลเคอร์เซอร์ของคุณควรจะแสดงขีดเส้นใต้ ไม่ใช่ตัวเลขแรกที่คุณพิมพ์สิ้นสุดอินพุตและแสดงอักขระ ดังนั้นคุณสามารถพิมพ์ U + 2620 ใน Bash โดยใช้สิ่งต่อไปนี้:

echo CTRL+ SHIFT+U2620ENTERENTER

(การป้อนครั้งแรกสิ้นสุดการป้อน Unicode และรายการที่สองรันechoคำสั่ง)

เครดิต: ถาม Ubuntu SE


1
แหล่งที่ดีสำหรับคะแนนรหัสhexademical
RobM

1
เวอร์ชันของ vim ที่ฉันใช้ (7.2.411 บน RHEL 6.3) ไม่ตอบสนองตามที่ต้องการเมื่อมีจุดระหว่าง ctrl-v และ u แต่ทำงานได้ดีเมื่อละเว้นจุดนั้น
Chris Johnson

@ChrisJohnson: ฉันได้ลบระยะเวลาออกจากคำแนะนำมันไม่ได้ตั้งใจจะเป็นปุ่มกด (ซึ่งเป็นสาเหตุที่มันไม่ปรากฏพร้อมกับเอฟเฟกต์คีย์บอร์ด) ขอโทษสำหรับความสับสน.
RobM

5
ระวัง: ใช้งานในเทอร์มินัลที่ใช้ Bash เฉพาะเมื่อคุณใช้งานภายใต้สภาพแวดล้อมGTK +เช่นเดียวกับ Gnome
nr

1
ความสามารถในการC-S-u 2 6 2 0เป็นคุณสมบัติของเทอร์มินัลอีมูเลเตอร์, วิธีการอินพุต X (XIM) หรือคล้ายกัน AFAIK คุณจะไม่สามารถส่งทั้งสองSHIFTและCTRLไปยังชั้นขั้ว เทอร์มินัลพูดเป็นตัวอักษรเท่านั้นแทนที่จะเป็น keysyms และรหัสเช่นเซิร์ฟเวอร์ X ของคุณ (เช่นกันมันคือ 7 บิตสำหรับจุดประสงค์และจุดประสงค์ทั้งหมด) ในโลกนี้มาสCTRLก์ 4 บิตที่สำคัญที่สุด (& 0b00001111) ซึ่งส่งผลให้
nabin-info

31

นี่คือการใช้ Bash ภายในอย่างสมบูรณ์ไม่มีฟอร์กขนาดไม่ จำกัด ของอักขระ Unicode

fast_chr() {
    local __octal
    local __char
    printf -v __octal '%03o' $1
    printf -v __char \\$__octal
    REPLY=$__char
}

function unichr {
    local c=$1    # Ordinal of char
    local l=0    # Byte ctr
    local o=63    # Ceiling
    local p=128    # Accum. bits
    local s=''    # Output string

    (( c < 0x80 )) && { fast_chr "$c"; echo -n "$REPLY"; return; }

    while (( c > o )); do
        fast_chr $(( t = 0x80 | c & 0x3f ))
        s="$REPLY$s"
        (( c >>= 6, l++, p += o+1, o>>=1 ))
    done

    fast_chr $(( t = p | c ))
    echo -n "$REPLY$s"
}

## test harness
for (( i=0x2500; i<0x2600; i++ )); do
    unichr $i
done

ผลลัพธ์คือ:

─━│┃┄┅┆┇┈┉┊┋┌┍┎┏
┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟
┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯
┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿
╀╁╂╃╄╅╆╇╈╉╊╋╌╍╎╏
═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟
╠╡╢╣╤╥╦╧╨╩╪╫╬╭╮╯
╰╱╲╳╴╵╶╷╸╹╺╻╼╽╾╿
▀▁▂▃▄▅▆▇█▉▊▋▌▍▎▏
▐░▒▓▔▕▖▗▘▙▚▛▜▝▞▟
■□▢▣▤▥▦▧▨▩▪▫▬▭▮▯
▰▱▲△▴▵▶▷▸▹►▻▼▽▾▿
◀◁◂◃◄◅◆◇◈◉◊○◌◍◎●
◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟
◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯
◰◱◲◳◴◵◶◷◸◹◺◻◼◽◾◿

ฉันอยากรู้ว่าเหตุผลที่อยู่เบื้องหลังวิธีการแบบรอบและการใช้งานเฉพาะของตัวแปร REPLY ฉันสมมติว่าคุณตรวจสอบแหล่งทุบตีหรือวิ่งผ่านหรือบางสิ่งบางอย่างเพื่อเพิ่มประสิทธิภาพซึ่งฉันสามารถดูว่าตัวเลือกของคุณสามารถเพิ่มประสิทธิภาพได้อย่างไรแม้ว่าจะขึ้นอยู่กับล่าม)
nabin-info

14

เพียงแค่ใส่ "☠" ลงในเชลล์สคริปต์ของคุณ ในสถานที่ที่ถูกต้องและบนคอนโซลที่เปิดใช้งาน Unicode มันจะทำการพิมพ์ได้ดี:

$ echo 

$

"วิธีแก้ปัญหา" ที่น่าเกลียดคือการส่งออกลำดับ UTF-8 แต่ยังขึ้นอยู่กับการเข้ารหัสที่ใช้:

$ echo -e '\xE2\x98\xA0'

$

13

ซับด่วนหนึ่งเส้นเพื่อแปลงอักขระ UTF-8 เป็นรูปแบบ 3 ไบต์:

var="$(echo -n '☠' | od -An -tx1)"; printf '\\x%s' ${var^^}; echo

5
ฉันจะไม่เรียกตัวอย่างข้างต้นอย่างรวดเร็ว (มี 11 คำสั่งและ params ของพวกเขา) ... นอกจากนี้มันจะจัดการ 3 ไบต์ UTF-8 chars` เท่านั้น (UTF-8 ตัวอักษรสามารถเป็น 1, 2 หรือ 3 ไบต์) ... นี่ สั้นลงเล็กน้อยและใช้ได้กับ 1-3 ++++ ไบต์: printf "\\\x%s" $(printf '☠'|xxd -p -c1 -u).... xxdจัดส่งเป็นส่วนหนึ่งของแพ็คเกจ 'vim-common'
Peter.O

PS: ฉันเพิ่งสังเกตว่าตัวอย่าง hexdump / awk ข้างต้นคือการเรียงลำดับของไบต์ในไบต์คู่ สิ่งนี้ไม่ได้ใช้กับการถ่ายโอนข้อมูล UTF-8 มันจะ relavent ถ้าเป็นการถ่ายโอนข้อมูลของ UTF-16LE และต้องการเอาท์พุท Unicode Codepointsแต่มันไม่สมเหตุสมผลที่นี่เนื่องจากอินพุตคือ UTF-8 และเอาต์พุตตรงตามอินพุต (บวก \ x ก่อนแต่ละ hexdigit -pair)
Peter.O

7
อักขระ UTF-8 สามารถมีได้ 1 - 4 ไบต์ตามลำดับ
cms

1
ขึ้นอยู่กับความคิดเห็นของ @ Peter.O ผมพบต่อไปนี้ในขณะที่มีขนาดใหญ่ที่มีประโยชน์สวย:hexFromGlyph(){ if [ "$1" == "-n" ]; then outputSeparator=' '; shift; else outputSeparator='\n'; fi for glyph in "$@"; do printf "\\\x%s" $(printf "$glyph"|xxd -p -c1 -u); echo -n -e "$outputSeparator"; done } # usage: $ hexFromGlyph ☠ ✿ \xE2\x98\xA0 \xE2\x9C\xBF $ hexFromGlyph -n ☠ ✿ \xE2\x98\xA0 \xE2\x9C\xBF
StephaneAG

2
มนุษย์พระเจ้าที่ดี ลองพิจารณา: codepoints () { printf 'U+%04x\n' ${@/#/\'} ; } ; codepoints A R ☯ 🕉 z ... เพลิดเพลินไปกับ👍
nabin-info

8

ฉันใช้สิ่งนี้:

$ echo -e '\u2620'

มันค่อนข้างง่ายกว่าการค้นหาการแสดงเลขฐานสิบหก ... ฉันใช้มันในเชลล์สคริปต์ของฉัน สิ่งนี้ใช้ได้กับคำพังเพยและคำ AFX ของ AFAIK


2
@masukomi ถ้าคุณรู้วิธีการชงคุณสามารถติดตั้งทุบตีใหม่และใช้มันได้ ข้างต้นทำงานได้ดีบนเครื่อง mac ของฉันเมื่อใช้ bash ที่อัพเกรด
mcheema

ใช่มันใช้ได้กับ bash เวอร์ชั่นใหม่กว่า สตริงพรอมต์ของ Hower เช่น $ PS1 ไม่ใช้รูปแบบ echo escape
cms

6

คุณอาจต้องเข้ารหัสจุดรหัสเป็นฐานแปดเพื่อให้การขยายตัวอย่างรวดเร็วเพื่อถอดรหัสอย่างถูกต้อง

U + 2620 เข้ารหัสเป็น UTF-8 คือ E2 98 A0

ดังนั้นใน Bash

export PS1="\342\230\240"

จะทำให้เปลือกของคุณพรอมต์เป็นกะโหลกศีรษะและกระดูก


สวัสดีรหัสที่ฉันควรป้อนสำหรับ "e0 b6 85" คืออะไร? ฉันจะหามันได้อย่างไร
Udayantha Udy Warnasuriya

เพียงแปลงเลขฐานสิบหก (ฐาน 16) e0 b6 85 เป็นฐานแปด (ฐาน 8) - การใช้เครื่องคิดเลขน่าจะเป็นวิธีที่ง่ายที่สุดในการทำเช่นนี้
cms

e0 b6 85 hex คือ 340 266 205 octal
cms

มันใช้งานได้ดีขอบคุณมาก! และ btw คุณสามารถค้นหาเวอร์ชันฐานแปดได้ที่หน้าเหล่านี้: graphemica.com/%E2%9B%B5
Perlnika

6

ในการทุบตีเพื่อพิมพ์อักขระ Unicode เพื่อส่งออกให้ใช้ \ x, \ u หรือ \ U (ครั้งแรกสำหรับเลขฐานสิบหก 2 หลักที่สองสำหรับเลขฐานสิบหก 4 หลักที่สามสำหรับความยาวใด ๆ )

echo -e '\U1f602'

ฉันต้องการกำหนดให้ตัวแปรใช้ $ '... ' ไวยากรณ์

x=$'\U1f602'
echo $x

5

หากคุณไม่สนใจ Perl one-liner:

$ perl -CS -E 'say "\x{2620}"'

-CSเปิดใช้งานการถอดรหัส UTF-8 บนอินพุตและการเข้ารหัส UTF-8 บนเอาต์พุต -Eประเมินผลอาร์กิวเมนต์ถัดไปเป็น Perl ด้วยคุณลักษณะที่ทันสมัยเช่นsayเปิดใช้งาน หากคุณไม่ต้องการขึ้นบรรทัดใหม่ในตอนท้ายให้ใช้แทนprintsay


5

คำสั่งสามคำสั่งใด ๆ เหล่านี้จะพิมพ์อักขระที่คุณต้องการในคอนโซลหากคอนโซลยอมรับอักขระ UTF-8 (คำสั่งที่เป็นปัจจุบันส่วนใหญ่):

echo -e "SKULL AND CROSSBONES (U+2620) \U02620"
echo $'SKULL AND CROSSBONES (U+2620) \U02620'
printf "%b" "SKULL AND CROSSBONES (U+2620) \U02620\n"

SKULL AND CROSSBONES (U+2620) 

หลังจากนั้นคุณสามารถคัดลอกและวางรูปสัญลักษณ์ (รูปภาพ, อักขระ) ที่แท้จริงไปยังตัวแก้ไขข้อความ (เปิดใช้งาน UTF-8)

หากคุณต้องการดูว่า Unicode Code Point นั้นเข้ารหัสใน UTF-8 อย่างไรให้ใช้ xxd (โปรแกรมดู hex ที่ดีกว่า od):

echo $'(U+2620) \U02620' | xxd
0000000: 2855 2b32 3632 3029 20e2 98a0 0a         (U+2620) ....

That means that the UTF8 encoding is: e2 98 a0

หรือใน HEX เพื่อหลีกเลี่ยงข้อผิดพลาด: 0xE2 0x98 0xA0 นั่นคือค่าระหว่างช่องว่าง (HEX 20) และ Line-Feed (Hex 0A)

หากคุณต้องการดำน้ำลึกในการแปลงตัวเลขเป็นตัวอักษร: ดูที่นี่เพื่อดูบทความจาก Greg's wiki (BashFAQ) เกี่ยวกับการเข้ารหัส ASCII ใน Bash!


เรื่อง: "หรือใน HEX เพื่อหลีกเลี่ยงข้อผิดพลาด ... " ฉันแทบจะไม่คิดว่าการแปลง unicode char เป็นการเข้ารหัสแบบไบนารี่ที่คุณแสดงออกมาใน hex chars ช่วยหลีกเลี่ยงข้อผิดพลาด การใช้สัญลักษณ์ยูนิโค้ดใน "bash" จะช่วยหลีกเลี่ยงข้อผิดพลาดได้ดีกว่า: "\ uHHHH --- อักขระ Unicode (ISO / IEC 10646) ซึ่งมีค่าเป็นค่า ---- เลขฐานสิบหก HHHH (หนึ่งถึงสี่หลักสิบหก); \ UHHHHHHHHHH ---- ตัวอักษร Unicode (ISO / IEC 10646) ที่มีค่าเป็นค่า ---- เลขฐานสิบหก HHHHHHHHH (หนึ่งถึงแปดหลักหก)
Astara

4

printfbuiltin (เช่นเดียวกับ coreutils' printf) รู้\uลำดับหนีซึ่งรับ 4 หลักอักขระ Unicode:

   \uHHHH Unicode (ISO/IEC 10646) character with hex value HHHH (4 digits)

ทดสอบด้วย Bash 4.2.37 (1):

$ printf '\u2620\n'

printf ยังเป็นเชลล์ในตัว คุณอาจใช้ค่าเริ่มต้นของ macOS bash (v3) ลองกับ\printfที่จะใช้ปฏิบัติการแบบสแตนด์อโลนหรือลองกับอัพเกรดทุบตี
mcint

4

ขออภัยสำหรับการคืนคำถามเก่านี้ แต่เมื่อใช้bashมีวิธีง่ายมากในการสร้าง Unicode codepoints จากอินพุต ASCII ธรรมดาซึ่งแม้จะไม่แยกเลย:

unicode() { local -n a="$1"; local c; printf -vc '\\U%08x' "$2"; printf -va "$c"; }
unicodes() { local a c; for a; do printf -vc '\\U%08x' "$a"; printf "$c"; done; };

ใช้มันดังต่อไปนี้เพื่อกำหนด codepoints บางอย่าง

unicode crossbones 0x2620
echo "$crossbones"

หรือถ่ายโอน codepoints 65536 unicode แรกไปยัง stdout (ใช้เวลาน้อยกว่า 2 วินาทีบนเครื่องของฉันพื้นที่เพิ่มเติมคือการป้องกันไม่ให้ตัวละครบางตัวไหลเข้าหากันเนื่องจากตัวอักษร monospace ของเชลล์):

for a in {0..65535}; do unicodes "$a"; printf ' '; done

หรือเพื่อบอกเล่าเรื่องราวของผู้ปกครองทั่วไปเล็กน้อย (สิ่งนี้ต้องการ Unicode 2010):

unicodes 0x1F6BC 32 43 32 0x1F62D 32 32 43 32 0x1F37C 32 61 32 0x263A 32 32 43 32 0x1F4A9 10

คำอธิบาย:

  • printf '\UXXXXXXXX' พิมพ์อักขระ Unicode ใด ๆ
  • printf '\\U%08x' numberพิมพ์\UXXXXXXXXด้วยจำนวนที่แปลงเป็น Hex จากนั้นจะถูกป้อนไปที่อื่นprintfเพื่อพิมพ์อักขระ Unicode
  • printf รู้จักเลขฐานแปด (0oct), เลขฐานสิบหก (0xHEX) และทศนิยม (0 หรือตัวเลขที่ขึ้นต้นด้วย 1 ถึง 9) เป็นตัวเลขดังนั้นคุณสามารถเลือกได้ว่าการแสดงใดที่เหมาะที่สุด
  • printf -v var ..รวบรวมผลลัพธ์ของprintfการเป็นตัวแปรโดยไม่ต้องแยก (ซึ่งเร็วขึ้นอย่างมากสิ่งต่าง ๆ )
  • local variable จะไม่มีการสร้างมลภาวะเนมสเปซส่วนกลาง
  • local -n var=otherนามแฝงvarไปotherเช่นการมอบหมายให้ที่altersvar otherส่วนที่น่าสนใจหนึ่งที่นี่คือที่varเป็นส่วนหนึ่งของ namespace ท้องถิ่นในขณะที่otherเป็นส่วนหนึ่งของ namespace ทั่วโลก
    • โปรดทราบว่าไม่มีสิ่งดังกล่าวเป็นlocalหรือglobalnamespace bashใน ตัวแปรจะถูกเก็บไว้ในสภาพแวดล้อมและเช่นนั้นเป็นระดับโลกเสมอ เฉพาะที่จะทำให้ค่าปัจจุบันหายไปและกู้คืนเมื่อฟังก์ชันถูกทิ้งอีกครั้ง ฟังก์ชั่นอื่น ๆ ที่เรียกจากภายในฟังก์ชั่นด้วยlocalจะยังคงเห็นค่า "ท้องถิ่น" นี่เป็นแนวคิดพื้นฐานที่แตกต่างจากกฎการกำหนดขอบเขตปกติที่พบในภาษาอื่น (และสิ่งที่bashมีประสิทธิภาพมาก แต่อาจนำไปสู่ข้อผิดพลาดหากคุณเป็นโปรแกรมเมอร์ที่ไม่ทราบว่า)

ดี - ไม่ได้ผลเลยสำหรับฉัน ความพยายามใด ๆ ที่จะใช้ฟังก์ชั่นของคุณ emits: บรรทัดที่ 6: ท้องถิ่น: -n: ตัวเลือกที่ไม่ถูกต้องท้องถิ่น: การใช้งาน: ชื่อท้องถิ่น [= ค่า] ... ฉันใช้ล่าสุด (10.14.2) MacOS และทุบตี (ทุบตี GNU) , รุ่น 3.2.57 (1) - ปล่อยออกมา (x86_64-apple-darwin18))
Motti Shneor

4

นี่คือรายการของ unicode emoji ทั้งหมดที่มีอยู่:

https://en.wikipedia.org/wiki/Emoji#Unicode_blocks

ตัวอย่าง:

echo -e "\U1F304"
🌄

รับค่า ASCII ของตัวละครนี้ใช้ hexdump

echo -e "🌄" | hexdump -C

00000000  f0 9f 8c 84 0a                                    |.....|
00000005

จากนั้นใช้ค่าที่แจ้งในรูปแบบฐานสิบหก

echo -e "\xF0\x9F\x8C\x84\x0A"
🌄

การสะท้อนสตริง \ U <hex> ไม่ทำงานบน OSX เพียงแค่แสดงผลลัพธ์ที่อยู่ในเครื่องหมายคำพูด
masukomi


2

ง่ายด้วย Python2 / 3 หนึ่งซับ:

$ python -c 'print u"\u2620"'    # python2
$ python3 -c 'print(u"\u2620")'  # python3

ผลลัพธ์ใน:


2

ใน Bash:

UnicodePointToUtf8()
{
    local x="$1"               # ok if '0x2620'
    x=${x/\\u/0x}              # '\u2620' -> '0x2620'
    x=${x/U+/0x}; x=${x/u+/0x} # 'U-2620' -> '0x2620'
    x=$((x)) # from hex to decimal
    local y=$x n=0
    [ $x -ge 0 ] || return 1
    while [ $y -gt 0 ]; do y=$((y>>1)); n=$((n+1)); done
    if [ $n -le 7 ]; then       # 7
        y=$x
    elif [ $n -le 11 ]; then    # 5+6
        y=" $(( ((x>> 6)&0x1F)+0xC0 )) \
            $(( (x&0x3F)+0x80 ))" 
    elif [ $n -le 16 ]; then    # 4+6+6
        y=" $(( ((x>>12)&0x0F)+0xE0 )) \
            $(( ((x>> 6)&0x3F)+0x80 )) \
            $(( (x&0x3F)+0x80 ))"
    else                        # 3+6+6+6
        y=" $(( ((x>>18)&0x07)+0xF0 )) \
            $(( ((x>>12)&0x3F)+0x80 )) \
            $(( ((x>> 6)&0x3F)+0x80 )) \
            $(( (x&0x3F)+0x80 ))"
    fi
    printf -v y '\\x%x' $y
    echo -n -e $y
}

# test
for (( i=0x2500; i<0x2600; i++ )); do
    UnicodePointToUtf8 $i
    [ "$(( i+1 & 0x1f ))" != 0 ] || echo ""
done
x='U+2620'
echo "$x -> $(UnicodePointToUtf8 $x)"

เอาท์พุท:

─━│┃┄┅┆┇┈┉┊┋┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟
┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿
╀╁╂╃╄╅╆╇╈╉╊╋╌╍╎╏═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟
╠╡╢╣╤╥╦╧╨╩╪╫╬╭╮╯╰╱╲╳╴╵╶╷╸╹╺╻╼╽╾╿
▀▁▂▃▄▅▆▇█▉▊▋▌▍▎▏▐░▒▓▔▕▖▗▘▙▚▛▜▝▞▟
■□▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱▲△▴▵▶▷▸▹►▻▼▽▾▿
◀◁◂◃◄◅◆◇◈◉◊○◌◍◎●◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟
◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷◸◹◺◻◼◽◾◿
U+2620 -> 

0

หากทราบค่าฐานสิบหกของอักขระ Unicode

H="2620"
printf "%b" "\u$H"

หากทราบค่าทศนิยมของอักขระยูนิโค้ด

declare -i U=2*4096+6*256+2*16
printf -vH "%x" $U              # convert to hex
printf "%b" "\u$H"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.