在 ASCII 表中,存在“J”字符,它在不同的数字系统中具有代码点:
Oct Dec Hex Char
112 74 4A J
可以通过打印
printf '\112'
或 来通过八进制代码点打印此字符echo $'\112'
。如何通过十进制和十六进制代码点表示打印相同的字符?
答案1
十六进制:
printf '\x4a'
十二月:
printf "\\$(printf %o 74)"
十六进制的替代方法:-)
xxd -r <<<'0 4a'
答案2
一般来说,shell 可以理解变量中的十六进制、八进制和十进制数字,只要它们被定义为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
因此,您只需要一种方法来打印属于变量值的字符。
但这里有两种可能的方法:
$ var=$((0x65))
$ printf '%b\n' "\\$(printf '0%o' "$var")"
e
$ declare -i var
$ var=0x65; printf '%b\n' "\U$(printf '%08x' "$var")"
e
需要两个 printf,一个将值转换为十六进制字符串,第二个实际打印字符。
第二个将打印任何 UNICODE 点(如果您的控制台设置正确)。
例如:
$ var=0x2603; printf '%b\n' "\U$(printf '%08x' "$var")"
☃
一个雪人。
具有 utf-8 表示形式的字符f0 9f 90 ae
如下0x1F42E
。搜索cow face site:fileformat.info
到得到它:
$ var=0x1F42F; printf '%b\n' "\U$(printf '%08x' "$var")"
答案3
十进制:
chr() {
local c
for c
do
printf "\\$((c/64*100+c%64/8*10+c%8))"
done
}
chr 74
十六进制:
chr $((16#4a))
该函数可以执行序列:
$ chr 74 75 76; echo
JKL
$
答案4
如果您有要转换的数字列表,并且希望避免函数调用并为每个字符创建子shell,则可以预先定义 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)
请注意,空字符被排除在外,因此每个字符都会偏移 1。
然后使用类似这样的内容(假设每行 1 个数字):
while read c; do out+="${ascii:$c-1:1}"; done <<< "$in"
echo "$out"