ฉันมีรายการ codepoints ของ Unicode แต่ฉันไม่รู้วิธี "ง่าย" ในการแปลงค่าเลขฐานสิบหกเหล่านี้ให้เป็นอักขระจริงที่พวกเขาเป็นตัวแทน ...
ฉันได้ยินว่าzshมีecho -e '\u0965'
แต่ฉันใช้bash 4.1
มีบางสิ่งที่ง่ายเหมือนวิธี zsh สำหรับทุบตี?
ฉันมีรายการ codepoints ของ Unicode แต่ฉันไม่รู้วิธี "ง่าย" ในการแปลงค่าเลขฐานสิบหกเหล่านี้ให้เป็นอักขระจริงที่พวกเขาเป็นตัวแทน ...
ฉันได้ยินว่าzshมีecho -e '\u0965'
แต่ฉันใช้bash 4.1
มีบางสิ่งที่ง่ายเหมือนวิธี zsh สำหรับทุบตี?
คำตอบ:
คุณสามารถใช้ echo ของ bash หรือ / bin / echo จาก GNU coreutils ร่วมกับ iconv:
echo -ne '\x09\x65' | iconv -f utf-16be
ตามค่าเริ่มต้น iconv จะแปลงเป็นการเข้ารหัสของโลแคล บางทีแบบพกพามากกว่าอาศัยเชลล์หรือคำสั่ง echo เฉพาะคือ Perl ระบบ UNIX ส่วนใหญ่ที่ฉันรู้จักในขณะที่มี Perl พร้อมใช้งานและยังมีพอร์ต Windows หลายพอร์ต
perl -C -e 'print chr 0x0965'
ส่วนใหญ่เวลาที่ฉันต้องทำสิ่งนี้ฉันอยู่ในเอดิเตอร์เช่น Vim / GVim ซึ่งมีการสนับสนุนในตัว ขณะอยู่ในโหมดแทรกให้กด Ctrl-V แล้วตามด้วย u จากนั้นพิมพ์อักขระฐานสิบหกสี่ตัว หากคุณต้องการตัวอักษรที่เกิน U + FFFF ให้ใช้ตัวพิมพ์ใหญ่ U และพิมพ์ตัวอักษรฐานสิบหก Vim ยังสนับสนุนการสร้างคีย์แมปแบบกำหนดเองได้อย่างง่ายดาย มันจะแปลงชุดอักขระเป็นสัญลักษณ์อื่น ตัวอย่างเช่นฉันมี keymap ที่ฉันพัฒนาขึ้นเรียกว่า www มันจะแปลง TM เป็น™, (C) เป็น©, (R) ถึง®และอื่น ๆ ฉันยังมี keymap สำหรับ Klingon สำหรับเมื่อจำเป็น ฉันแน่ใจว่า Emac มีบางอย่างที่คล้ายกัน หากคุณอยู่ในแอพ GTK + ซึ่งรวมถึง GVim และเทอร์มินัล GNOME คุณสามารถลอง Control-Shift-u ตามด้วยอักขระฐานสิบหก 4 ตัวเพื่อสร้างอักขระ Unicode ฉันแน่ใจว่า KDE / Qt มีบางอย่างที่คล้ายกัน
UPDATE:ในฐานะของ Bash 4.2 ดูเหมือนว่าจะมีฟีเจอร์ในตัวในขณะนี้:
echo $'\u0965'
ปรับปรุง:นอกจากนี้ในปัจจุบันตัวอย่างงูหลามอาจจะต้องการ Perl ใช้ได้ทั้ง Python 2 และ 3:
python -c 'print(u"\u0965")'
chr 0xa2
ในภาษา UTF-8 ฉันจะได้รับเซ็นต์เซ็นต์¢ แต่ถ้าฉันใช้ LANG = C ฉันจะได้ get เพราะมันพิมพ์ไบต์ 0xa2 ซึ่งไม่ถูกต้องใน UTF-8 ตัวอย่าง Vim / GVim มีความไวต่อกึ่งโลแคล การเข้ารหัสไฟล์ที่ถูกต้องมากขึ้น หากคุณเริ่มต้นเป็นกลุ่มในสถานที่ที่ไม่ใช่ UTF-8 คุณจะต้อง:set encoding=utf-8
chr 0x12000
ใน Perl (สมมติว่า Unicode ใช้งานได้) เพื่อแสดงมัน ใน UTF-16BE นี่คือ 0xd8, 0x08, 0xdc และ 0x00 อักขระของคุณคือ U + 0965 ซึ่งเพิ่งเกิดขึ้นเป็นไบต์ 0x09 ตามด้วย 0x65 ใน UTF-16BE
perl
คำตอบของคุณคือสิ่งที่ดีที่สุด (สำหรับข้อกำหนดเฉพาะของฉัน) .. ก่อนหน้านี้ฉันได้ตัดการพิมพ์ printf (เดือนก่อน) แต่ฉันลืมไปแล้ว นี่คือภารกิจ / คำตอบเกี่ยวกับข้อ จำกัด ของมัน ... เหตุใด printf จึงรายงานข้อผิดพลาดในทั้งหมดยกเว้น Unicode Codepoints (ASCII-range) สามอัน
ทุบตี 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.
bash 4.2.x
รุ่นที่มีข้อผิดพลาดที่ค่าระหว่าง0x80
และ0xff
( 128 - 255
) - คืออยู่ในช่วงขยาย ASCII - จะไม่ถูกต้อง UTF8 เข้ารหัสและแทนที่จะเป็นเพียงแค่ผ่านส่งผลให้ถ่าน UTF8 ?
ไม่ถูกต้องที่ขั้วบางทำให้เป็น ณ (อย่างน้อย) 4.3.11
สิ่งนี้ได้รับการแก้ไขแล้ว ถ้าecho $'\ued'
แสดงผลí
บั๊กจะไม่มีอยู่
หากคุณมี coreutils GNU ลองprintf
:
$ printf '\u0965\n'
॥
echo
สามารถทำงานได้ถ้าคอนโซลของคุณใช้ UTF-8 และคุณมีการเข้ารหัส UTF-8:
$ echo -e '\xE0\xA5\xA5'
คุณสามารถค้นหาตาราง Unicode เพื่อการเข้ารหัส UTF-8 ฐานสิบหกที่นี่: http://www.utf8-chartable.de/ คุณสามารถแปลงคะแนนโค้ด Unicode ให้เป็นเลขฐานสิบหกโดยใช้ภาษาสคริปต์จำนวนหนึ่ง นี่คือตัวอย่างการใช้งานไพ ธ อน:
python -c "print(unichr(int('0965', 16)).encode('utf-8').encode('hex'))"
ต่อไปนี้เป็นสคริปต์ Perl ที่จะแปลงอาร์กิวเมนต์เป็นค่าฐานสิบหกที่ถูกต้อง (วงเล็บที่ไม่จำเป็นจำนวนมากที่นี่):
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use Encode;
foreach (@ARGV) {
say unpack('H*', encode('utf8', chr(hex($_))))
}
ตัวอย่างเช่น
./uni2utf 0965
e0a5a5
แน่นอนว่าถ้าคุณมี Perl หรือ Python คุณก็สามารถใช้มันเพื่อพิมพ์อักขระได้
echo
สิ่งที่ฉันไม่ต้องการเพราะ Codepoints นั้นเป็น 2-byte UTF-16 Big-Endian .. แต่คุณได้เตือนฉันว่ามี2หน้าที่ printf! (ฉันคิดว่า printf สามารถทำได้และดูเหมือนว่าฉันกำลังเรียกผิด) ... ใช้$(which printf)
งานได้ ... ขอบคุณสำหรับตัวอย่างของไพ ธ อน .. แต่สำหรับเรื่องนี้ (เส้นโค้งการเรียนรู้ของฉัน) ฉันพยายามที่จะปิด เป็นไปได้ที่จะ "ทุบตี" เป็นภาษาที่แสกหน้าเท่านั้นที่เกี่ยวข้อง .. (เมื่อฉันสบายพอที่จะทุบตีฉันจะติดอยู่กับงูหลาม ... btw .encode('hex')
เป็นขั้นตอนเดียวที่เกินกว่าที่ฉันต้องการ .. (ฉันคิดว่ามันดู บิตว่างในการมี :)
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` ทางออกดูดีมากตอนนี้ :) .. มันเป็น invocaton เดียวและฉันหลังจาก "พิมพ์ง่าย" ดังนั้นฉันจะให้ เห็บสีเขียวสำหรับเขาperl
อัปเดต: นี่คือวิธีทุบตีในการทำค่า Unicode เดียว ... (โดย "ทุบตี" ฉันหมายถึง: ไม่ได้ใช้ภาษาสคริปต์อื่น ๆ ) .. ขอบคุณ Gilles สำหรับคำแนะนำในAskubuntu Q / Aนี้
ตามลิงค์นี้ : recode (Obsoletes iconv, dos2unix, unix2dos) .. แก้ไข:แต่ตามความคิดเห็นด้านล่าง "obsoletes 'อาจหมายถึง" ทางเลือก "
echo -n 0x0965 |recode UTF-16BE/x4..UTF-8
นี่คือวิธีการประมวลผลการถ่ายโอนข้อมูล hex ดิบเป็นอินพุต (เช่นไม่มีคำนำหน้าหนีเช่น; \ u0965 และไม่มี \ x09 \ x65) ..
xxd
เป็นยูทิลิตี้ hex-dump (บรรจุด้วยvim-common
) ซึ่งสามารถเปลี่ยนการถ่ายโอนข้อมูลดิบ hex สำหรับอักขระที่ดัมพ์แทน ... Unicode Codepoints คือ UTF-16BigEndian ซึ่งเป็นสิ่งที่ Hex-dump คือ ..
xxd
ในโหมดย้อนกลับยอมรับกระแสของค่า Hex ที่มีการแบ่งบรรทัดซึ่งจะถูกละเว้น
สคริปต์นี้สร้างสตรีม 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
นี่คือผลลัพธ์ (แสดงอินพุต hex-dump UTF-16BE ก่อน)
บันทึก; xxd
แบ่งกลุ่มเอาท์พุทของตัวเองด้วยการขึ้นบรรทัดใหม่ด้วยตัวเลขฐานสิบหก 60 ตัว ... ตัวเลือกการย้อนกลับจะละเว้นบรรทัดใหม่เหล่านี้ .. มันจะละเว้นการขึ้นบรรทัดใหม่ใด ๆ / ทั้งหมด
004D0061007400730075006F00200042006100730068006F002000280031
003600340034002D00310036003900340029000A
002000200070006F006E0064000A
0020002000660072006F00670020006A0075006D0070007300200069006E
000A
002000200070006C006F00700021000A
Matsuo Basho (1644-1694)
pond
frog jumps in
plop!
bash
วิธี โดย "bash" ฉันหมายถึง: ใช้ภาษาสคริปต์ทุบตี; ไม่ใช่ python / perl จากภายใน bash) ฉันได้เพิ่มสิ่งนี้เป็นคำตอบเพราะอาจมีค่าสำหรับบางคนที่อ่านหน้านี้ เป็นไฟล์เดียวที่ดีสำหรับไฟล์ทั้งหมด คุณprintf
คือคำตอบที่ดีที่สุดสำหรับฉัน
สมมติว่าการเข้ารหัสเริ่มต้นสำหรับระบบปฏิบัติการของคุณคือ UTF-8 (จริงสำหรับ distros ปัจจุบัน) จากนั้นคุณสามารถใช้ bash โดยตรงเพื่อแปลงจุดโค้ด UNICODE ใด ๆ :
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'
โปรดทราบว่าสำหรับ bash 4.2 โค้ด Unicode 0x80
จะ0xFF
ถูกเข้ารหัสอย่างไม่ถูกต้อง (bash bug) หากต้องการแก้ไขปัญหานี้คุณต้องดูที่โปรแกรมในไซต์นี้ (ซึ่งจะช่วยให้มองลึกลงไปถึงปัญหาของการแปลงตัวเลขเป็นตัวอักษร
ใช้รูปแบบการทดแทนในทุบตีรุ่น 4.2 (และสูงกว่า):
${parameter/pattern/string}
ตามที่อธิบายไว้ที่นี่http://steve-parker.org/sh/tips/pattern-substitution/
UNICODE_HEX="U+02211"
printf ${UNICODE_HEX/U+/"\U"}
∑
UNICODE_HEX="U+03BB"
printf ${UNICODE_HEX/U+/"\U"}
λ