ASCIIテーブルには、さまざまな数値システムのコードポイントを持つ「J」文字が存在します。
Oct Dec Hex Char
112 74 4A J
printf '\112'
またはecho $'\112'
を出力すると、この文字を8進コードポイントで出力できます。 10進数と16進数のコードポイント表示で同じ文字を印刷するにはどうすればよいですか?
16進数:
printf '\x4a'
12月:
printf "\\$(printf %o 74)"
16進数の代替:-)
xxd -r <<<'0 4a'
zsh
の場合:
$ printf '\x4a\n' # Hex
J
$ printf "\\$(([##8]74))\n" # Dec
J
Unicodeコードポイントから(現在の文字セットの)文字を取得するには:
$ printf '\U1F42E\n' # Hex
????
$ printf "\\U$(([##16]128046))\n" # Dec
????
一般に、シェルは、変数の16進数、10進数、10進数をintegers
として定義されていれば理解できます。
$ declare -i v1 v2 v3 v4 v5 v6 v7
$ v1=0112
$ v2=74
$ v3=0x4a
$ v4=8#112
$ v5=10#74
$ v6=16#4a
$ v7=18#gg
echo "$v1 $v2 $v3 $v4 $v5 $v6 $v7"
74 74 74 74 74 74 304
または、これらは「算術拡張」の結果です。
$ : $(( v1=0112, v2=74, v3=0x4a, v4=8#112, v5=10#74, v6=16#4a, v7=18#gg ))
$ echo "$v1 $v2 $v3 $v4 $v5 $v6 $v7"
74 74 74 74 74 74 304
したがって、変数値に属する文字を出力する1つの方法が必要です。
しかし、ここには2つの可能な方法があります。
$ var=$((0x65))
$ printf '%b\n' "\\$(printf '0%o' "$var")"
e
$ declare -i var
$ var=0x65; printf '%b\n' "\U$(printf '%08x' "$var")"
e
2つのprintfが必要です。1つは値を16進文字列に変換し、もう1つは実際に文字を出力します。
2番目は、任意のUNICODEポイントを出力します(コンソールが正しく設定されている場合)。
例えば:
$ var=0x2603; printf '%b\n' "\U$(printf '%08x' "$var")"
☃
雪だるま。
f0 9f 90 ae
としてutf-8表現を持つ文字は0x1F42E
です。 cow face site:fileformat.info
を検索して get it :
$ var=0x1F42F; printf '%b\n' "\U$(printf '%08x' "$var")"
????
注:4.3より前のbash(そのバージョン以降で修正済み)、UNICODEポイント128と255(10進数)が正しく印刷されない場合があります。
man bash
のPARAMETERS
内の4番目の段落:
変数に整数属性が設定されている場合、$((...))展開が使用されていなくても、値は算術式として評価されます(下記の算術展開を参照)。
man bash
の「ARITHMETIC EVALUATION」の内部:
先頭が0の定数は、8進数として解釈されます。先頭の0xまたは0Xは16進数を示します。それ以外の場合、数値の形式は[base#] nです。オプションの基数は、算術基数を表す2〜64の10進数で、nはその基数の数値です。 base#を省略すると、base 10が使用されます。 9より大きい数字は、小文字、大文字、@、および_の順で表されます。 baseが36以下の場合、小文字と大文字を同じ意味で使用して、10〜35の数値を表すことができます。
10進数:
chr() {
local c
for c
do
printf "\\$((c/64*100+c%64/8*10+c%8))"
done
}
chr 74
16進数:
chr $((16#4a))
関数はシーケンスを実行できます。
$ chr 74 75 76; echo
JKL
$
変換する数値のリストがあり、関数呼び出しを避け、各文字のサブシェルを作成したい場合は、事前にASCIIセットを定義できます。
ascii=$(for x in {0..9} {A..F}; do for y in {0..9} {A..F}; do echo -ne "\x$x$y"; done; done)
Null文字は除外されるため、すべての文字は1だけオフセットされることに注意してください。
次に、次のようなものを使用します(1行に1つの数値を想定しています):
while read c; do out+="${ascii:$c-1:1}"; done <<< "$in"
echo "$out"
POSIX Awk stdlibライブラリ を使用できます。
$ awklib 'BEGIN {print str_chr(74)}'
J
$ awklib 'BEGIN {print str_chr(+base_conv("4A", 16, 10))}'
J
$ awklib 'BEGIN {print str_chr(+base_conv(112, 8, 10))}'
J
$ awklib 'BEGIN {print str_chr(+base_conv(1001010, 2, 10))}'
J
printf
を使用したすべての変換は次のとおりです:
printf "%o" "'J" # 112 (oct)
printf "%d" "'J" # 74 (dec)
printf "%x" "'J" # 4a (hex)
printf '\112' # J (oct)
printf "\x$(printf %x 74)" # J (dec, requires double conversion)
printf '\x4a' # J (hex)