web-dev-qa-db-ja.com

bashで、Unicodeコードポイント[0-9A-F]を印刷可能な文字に変換するにはどうすればよいですか?

Unicodeコードポイントのリストがありますが、これらの16進値を、それらが表す実際の文字に変換する「簡単な」方法がわかりません...

zshにはecho -e '\u0965'、ただしbash 4.1を使用しています。

Bashの場合、zshメソッドと同じくらい簡単なものはありますか?

23
Peter.O

GNU coreutilsのiconvと組み合わせて、bashのエコーまたは/ bin/echoを使用できます。

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

デフォルトでは、iconvはロケールのエンコーディングに変換されます。おそらく、特定のシェルまたはエコーコマンドに依存するよりも移植性が高いのはPerlです。私が知っているほとんどすべてのUNIXシステムはPerlが利用可能であり、いくつかのWindowsポートさえ持っています。

Perl -C -e 'print chr 0x0965'

ほとんどの場合、これを行う必要があるときは、サポートが組み込まれているVim/GVimなどのエディターを使用しています。挿入モードで、Ctrl-Vに続けてuを押し、次に4つの16進文字を入力します。 U + FFFFを超える文字が必要な場合は、大文字のUを使用して8桁の16進文字を入力します。 Vimは、カスタムで簡単に作成できるキーマップもサポートしています。一連の文字を別の記号に変換します。たとえば、wwwと呼ばれる開発したキーマップがあります。これは、TMを™に、(C)を©に、(R)を®に変換します。また、必要になったときのクリンゴンのキーマップもあります。 Emacsにも同様の機能があると思います。 GVimとGNOME端末を含むGTK +アプリを使用している場合は、Ctrl-Shift-uに続けて4つの16進文字を入力して、Unicode文字を作成できます。 KDE/Qtにも同様の機能があると思います。

PDATE: Bash 4.2の時点では、組み込み機能のようです。

echo $'\u0965'

PDATE:また、最近ではPythonの例がおそらくPerlよりも好まれます。これはPython 2と3の両方で機能します:

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

Bash 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.
13
Lri

GNU coreutilsがある場合は、printfを試してください:

$ printf '\u0965\n'
॥

echoは、コンソールがUTF-8を使用していて、UTF-8エンコーディングを使用している場合に、この作業を実行できます。

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

UnicodeからUTF-8への16進エンコーディングの表は、次の場所にあります: http://www.utf8-chartable.de/ 。いくつかのスクリプト言語を使用して、Unicodeコードポイントを16進数に変換できます。 Pythonを使用した例を次に示します。

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

以下は、引数を正しい16進値に変換する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を使用している場合は、それらを使用して文字を印刷することもできます。

5
Steven D

更新:これは、単一のUnicode値を実行するbashの方法です...( "bash"によって:別のスクリプト言語を使用しません)..この提案に対するGillesへの感謝 askubuntu Q/A
によるとこのリンク:recode(Obsoletes iconv、dos2unix、unix2dos)..Edit :しかし、以下のコメントのとおり、「廃止」は単に「代替」を意味する場合があります

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

これはraw16進ダンプを入力として処理する方法です(つまり、\ u0965のようなエスケープされたプレフィックスはなく、\ x09\x65はありません)。 。
xxdは、16進ダンプユーティリティです(vim-common)は、生の16進ダンプをダンプが表す文字に戻すことができます... UnicodeコードポイントはUTF-16BigEndianであり、16進ダンプとまったく同じです。
復帰モードの xxdは、改行付きの16進値のストリームを受け入れます。無視されます。

このスクリプトは、UTF-16BEストリームを作成し、それを元の文字に戻します。
最後の行には、必要な2つのコマンドが含まれています。 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 16進ダンプ入力を最初に示しています)。
注意; xxdは、独自の出力を60桁の16進数の改行でセグメント化します... revertオプションは、これらの改行を無視します。すべての改行を無視します(16進数ではないため)。

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

Matsuo Basho (1644-1694)
  pond
  frog jumps in
  plop!
2
Peter.O

Bashバージョン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"}
λ         
1
illucent

OSのデフォルトのエンコーディングがUTF-8(ほとんどの最新のディストリビューションではtrue)であるとすると、bashを直接使用して、任意のUNICODEコードポイントを変換できます。

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

もちろん、グリフは正しいフォントを持っている場合にのみ正しく表示されます。 bash 4.3以降、すべてのコードポイントが正しく機能します。また、この2つの組み込みオプションも機能します。

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

Bash 4.2の場合、Unicodeコードは0x80から0xFFは正しくエンコードされていません(bashバグ)。この問題を回避するには、プログラムを このサイト で確認する必要があります(数値を文字に変換する問題を詳しく調べるのにも適しています。

1
user79743