Kısaca, Unicode Kod Noktasını [0-9A-F] nasıl yazdırılabilir bir karaktere dönüştürebilirim?


23

Unicode kod noktalarının bir listesi var, ancak bu onaltılık değerleri temsil ettikleri gerçek karakterlere dönüştürmenin "basit" bir yolunu bilmiyorum ...

Ben duydum zsh vardır echo -e '\u0965', ama kullanmak bash 4.1.

Bash için zsh yöntemi kadar basit bir şey var mı?


Yanıtlar:


16

Bash echo veya / bin / echo komutunu GNU coreutils'den iconv ile birlikte kullanabilirsiniz:

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

İconv varsayılan olarak yerel kodlama sistemine dönüştürür. Belki de belirli bir kabuk veya yankı komutuna güvenmekten daha taşınabilir. Perl. Perl’im varken bildiğim herhangi bir UNIX sistemi ve hatta birkaç tane Windows bağlantı noktası var.

perl -C -e 'print chr 0x0965'

Bunu yapmak istediğimde çoğu zaman, yerleşik desteği olan Vim / GVim gibi bir editördeyim. Ekleme modundayken, Ctrl-V tuşlarına ve ardından u tuşuna, ardından dört onaltılık karakter yazın. U + FFFF'nin ötesinde bir karakter istiyorsanız, büyük U harfini kullanın ve 8 onaltılık karakter yazın. Vim ayrıca, keymaps yapmak için özel kolay destekler. Bir dizi karakteri başka bir sembole dönüştürür. Örneğin, www olarak geliştirdiğim bir anahtar eşlemim var, TM'yi ™, (C) 'yi ©, (R)' yi ® 'e dönüştürür. Ayrıca gerekli olduğunda Klingon için bir anahtar haritam var. Eminim Emacs'in benzer bir şeyi vardır. GVim ve GNOME Terminali içeren bir GTK + uygulamasındaysanız, Unicode karakterini oluşturmak için Control-Shift-u ardından 4 hex karakterini deneyebilirsiniz. Eminim KDE / Qt da buna benzer bir şeydir.

GÜNCELLEME: Bash 4.2'den itibaren, şu anda yerleşik bir özellik olarak görünüyor:

echo $'\u0965'

GÜNCELLEME: Ayrıca, bugünlerde bir Python örneği muhtemelen Perl'e tercih edilecektir. Bu hem Python 2 hem de 3'te çalışır:

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

Teşekkürler ... perl one in nazik ve hoş, ama bana değeri UTF-16BE olarak nasıl kullanacağını bildiği konusunda biraz şaşkınlık verdi. Sanırım "chr" nin ne anlama geldiğini ...
Peter.O

@fred bu iyi bir nokta. Perl örneği yerel ayarlara duyarlıdır. -C tam Unicode işlemeyi sağlar, ancak örnek yerel ayarımda Unicode örneği kullandığından çalışır. LANG'ı C'ye ayarlarsam, baskıda geniş bir karakter hakkında bir uyarı alırım, ancak yine de yazdırır. chr 0xa2Bir UTF-8 yerel ayarında yazdırırsam sign işareti alırım, ancak LANG = C kullanırsam, alırım çünkü UTF-8'de geçersiz olan bayt 0xa2'yi yazdırır. Vim / GVim örneği yerel ayarlara yarı duyarlıdır. Daha doğrusu, dosya kodlamasına. Eğer Vim'e UTF-8 yerel ayarlarında başladıysanız, yapmanız gerekenler:set encoding=utf-8
penguin359

@fred belirtmeliyim ki, Perl UTF-8 gibi bir Unicode yerel ayarında başlatıldıysa, chr değerini bir Unicode kod noktası olarak kabul edin. Kod noktası, bir karakteri temsil eden ve UTF-16BE veya UTF-8 gibi herhangi bir kodlamaya bağlı olmayan benzersiz sayıdır. Çıktılan zaman doğru kodlamaya dönüştürür. Örneğin, Çivi yazısı işareti A kod noktası U + 012000'dir. I kullanabilir chr 0x12000(Unicode varsayarak aktiftir) temsil etmek Perl. UTF-16BE'de bu, 0xd8, 0x08, 0xdc ve 0x00'dir. Siz karakteriniz U + 0965, UTF-16BE de 0x65 olan bayt olur.
penguin359

@ penguin359 .. Teşekkürler, bir gün (inşallah) Perl'e iyi bakacağım .. Anlaşılmaz derecede şifreli görünüyor, ama sonra baştan kalktı ve regex, başlangıçta, ve şimdi oldukça kolay ... belki biraz vim gibi; dik bir öğrenme eğrisi, sonra düz yelken .... Açıklamanı okumak güzel ... yolu açıyor ..
Peter.O

Ben sadece (yeniden) Steven D'nin printf ruhunun unicode aralığının ASCII bloğunu kullanmayacağını keşfettim , bu yüzden perlcevabınız şimdi en iyisidir (özel gereksinimlerime göre) .. daha önce printf'i reddetmiştim (aylar önce) , ama unutmuştum. İşte limitleri hakkında soru / cevap ... printf neden üç (ASCII) Unicode Kod Noktaları dışında bir hata rapor ediyor
Peter.O

13

Bash 4.2 (2011 yılında yayımlanan) desteği eklendi echo -e '\u0965', printf '\u0965', printf %b '\u0965've echo $'\u0965'aynı zamanda iş.

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

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

Teşekkürler ... Hala birincil olarak Ubuntu 10.04'te 4.1.5 bash kullanıyorum, ancak şu anda 4.2'de mevcut olduğunu bilmek güzel. (+1)
Peter.O 14.03.03:

1
+ 1; bash 4.2.xSürümlerin 0x80ve 0xff( 128 - 255) arasındaki ( yani genişletilmiş ASCII aralığındaki) doğru UTF8 kodlu DEĞİLDİR ve bunun yerine sadece geçtiği, bazı terminallerin oluşturduğu geçersiz bir UTF8 karakteriyle sonuçlanan bir hata olduğunu unutmayın ?. (En azından) itibariyle 4.3.11bu sorun giderildi; eğer echo $'\ued'işlerse í, böcek mevcut değildir .
mklement0

5

GNU coreutils'iniz varsa, şunu deneyin printf:

$ printf '\u0965\n'

echo Konsolunuz UTF-8 kullanıyorsa ve UTF-8 kodlamasına sahipseniz işi yapabilirsiniz:

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

Unicode - UTF-8 hex kodlama tablosunu burada bulabilirsiniz: http://www.utf8-chartable.de/ . Bir dizi komut dosyası dili kullanarak Unicode kod noktalarını hex'e dönüştürebilirsiniz. İşte python kullanarak bir örnek:

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

Aşağıda, argümanları doğru onaltılı değere dönüştürecek bir Perl betiği verilmiştir (burada pek çok gereksiz parantez):

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

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

Örneğin,

./uni2utf 0965
e0a5a5

Tabii ki, eğer Perl veya Python'unuz varsa, karakterleri yazdırmak için de kullanabilirsiniz.


Teşekkürler .. echoCodepoints 2-byte UTF-16 Big-Endian gibi, istediğimi yapmayacak .. ama 2 tane printf işlevi olduğunu hatırlattın ! (Printf'in yapabileceğini düşündüm ve yanlış olanı çağırıyor gibi göründüm) ... $(which printf)işe yarıyor ... python örneği için teşekkürler .. ama bunun için (öğrenme eğrime) yakın durmaya çalışıyorum mümkün olan tek yazı dili olarak "bash" yapmak mümkün ... (bash ile yeterince rahat olduğumda, Python'a sıkışıp kalacağım ... btw, .encode('hex')ihtiyacım olanın ötesinde bir adım .. (baktım sandım) orada biraz meşgul :)
Peter.O

Evet, .encode ('hex') sadece benim için yankı ile çalışıyor gibi görünen hex kodunu almaktı. Bunun en azından bir kısmının faydalı olduğuna sevindim.
Steven D

Şimdi sizi perl snippet'ini gördüm .. teşekkürler ... bu çeşitli çözümleri tabloya koymak iyi ... Printf one tam olarak aradığım şeydi (zsh örneğine göre tek bir komut) ... .. Bir hex veri akışı (no \ u, vb) üzerinde çalışan bir başka-scripting- benim
dilimi

Ben özellikle printfyukarıdakilerin kısalıklarından hoşlanıyorum , ancak aşağıdaki değerleri ele ... 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* almıyor, `` \ u00A0 perl` çözümü şu anda oldukça iyi görünüyor :) .. Tek bir istila ve "yazması kolay" dan sonra, ben de vereceğim Onu yeşil keneperl
Peter.O

2

GÜNCELLEME: İşte tek bir Unicode değeri yapmanın basit bir yolu ... ("bash" ile demek istiyorum: başka bir betik dili kullanmamak) .. Bu askubuntu Q / A'daki öneri için Gilles'a teşekkürler . Bu bağlantıya
göre : yeniden kodlayın (Obsoletes iconv, dos2unix, unix2dos) .. Düzenleyin: ancak aşağıdaki yoruma göre "eski" sadece "alternatif" anlamına gelebilir

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

Burada işlemek için bir yöntemdir , ham giriş olarak altıgen dökümü (. Örneğin, bir kaçan-önekleri benzerleri; \ u0965 ve hiçbir \ X09 \ X65) ..
xxdbir heks-dökümü programı ile (paketlenir vim-commonham heks dökümü geri olabilir) Unicode Kod Noktaları UTF-16BigEndian'dır, ki bu tam olarak bir Hex-dökümüdür
xxd. geri döndürme modunda satır sonları ile birlikte bir Hex değerleri akışını kabul eder.

Bu komut, daha sonra orijinal karakterlere geri döndüren bir UTF-16BE akışı oluşturur.
Son satır iki gerekli komutu içerir; xxdveiconv

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

İşte çıktı (önce UTF-16BE hex-damping girişini gösteren).
Not; xxdkendi çıktısını 60 altı basamaklı bir yeni satırla bölümlere ayırır ... Geri döndürme seçeneği bu yeni satırları yok sayar. Tüm yeni satırları yok sayar.

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

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

Cevabınızda penguen359'un bilgilerini kullandığınız görülüyor olduğundan, cevabını benimki yerine doğru olarak işaretleyebilirsiniz.
Steven D,

@Steven D: dikkate değer bir yorum, ancak "kelime" operatif kelimedir. Iconv'yi birkaç gündür kullanıyorum, bu da tek bir komut olup olmadığını merak etmemi sağladı. Pencerelerde (C ++) benzer tüm dosya işlemlerini yaptım, bu yüzden Unicode hakkında bir sebep bilgisi anlıyorum. Gerçekten hızlı ve basit bir bashyöntemin peşindeydim. "Bash" ile demek istediğim: bash betik dilini kullanmak; bash içinden python / perl değil). Bunu bir cevap olarak ekledim, çünkü bu sayfayı okuyan biri için bir değeri olabilir. Tüm bir dosya için tek bir gömlek iyidir. Sizin printfbenim için en iyi cevaptır.
Peter.O

2
Recode obsolet iconv'yi söyleyemem, aslında recode iconv'den daha eskidir ve bu günlerde iconv varsayılan olarak recode'dan çok daha yaygın olarak kurulmaktadır (örneğin, Linux'ta, iconv neredeyse her zaman libc ile birlikte gelir çünkü yüklenir).
Gilles 'SO- kötülük'

Teşekkürler .. Bunu merak ediyordum .. Bu web sayfası tam olarak kesin bir referans değil ... bu yüzden daha fazla alternatif ...
Peter.O

1

İşletim sisteminiz için varsayılan kodlamanın UTF-8 olduğunu varsayalım (çoğu geçerli dağıtım için geçerlidir), ardından herhangi bir UNICODE kod noktasını dönüştürmek için doğrudan bash kullanabilirsiniz:

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

Tabii ki, glif sadece doğru yazı tipine sahipseniz doğru görünecektir. Bash 4.3'ten itibaren tüm kod noktaları düzgün çalışacaktır. Ve bu iki yerleşik seçenek de işe yarayacak:

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

Bash 4.2 Unicode kod noktaları bu Not 0x80için 0xFFyanlış kodlanır (Bash bir hata). Bu sorunu gidermek için, bu sitedeki programa bir göz atmanız gerekir (ayrıca sayıları karaktere dönüştürme konusuna derinlemesine bir göz atmak için de iyi olur.


Bash 4.3 ve zsh'de benim için çalışıyor. Bash 4.2 için link verebileceğiniz bir hata raporu var mı?
Mikel

: Doğru böcek gibi bana bakar https://lists.gnu.org/archive/html/bug-bash/2012-02/msg00035.htmlAçıklama: arasına \ u ve \ U yanlış kodlama değerleri \ U80 ve \ uff

0

Bash 4.2 sürümünde (ve üstü) Desen değiştirme özelliğini kullanma:

${parameter/pattern/string}

Burada açıklandığı gibi 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"}
λ         

1
O Not belirtildiği gibi bir önceki cevabı , bu sadece bash sürüm 4.2 (ve üstü) çalışır. Aslında, bu önceki cevaba oldukça az ekler.
G-Man 'Yenilenmiş Monica'yı'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.