BASH 基数从十进制转换为十六进制

BASH 基数从十进制转换为十六进制

在 Bash 中,如何从十进制进行基数转换另一个基数,尤其是十六进制。走另一条路似乎很容易:

$ echo $((16#55))
85

通过网络搜索,我找到了一个可以进行数学和字符操作来进行转换的脚本,我可以将其用作函数,但我认为 bash 已经有一个内置的基数转换了——可以?

答案1

使用bash(或任何 shell,前提是该printf命令可用(通常在 shell 中内置的标准 POSIX 命令)):

printf '%x\n' 85

​​​​​​​​​​​​​​​​ 使用zsh,您还可以执行以下操作:

dec=85
hex=$(([##16]dec))

这适用于 2 到 36 的基数(0-9a-z数字不区分大小写)。

$(([#16]dev))如果启用该选项,(只有一个#)将扩展为16#55or 0x55(作为基数 16 的特殊情况) (如果也启用了该cbases选项,也适用于基数 8(0125而不是) )。8#125octalzeroes

通过ksh93,您可以使用:

dec=85
base54=${ printf %..54 "$dec"; }

适用于 2 到 64 的碱基(与0-9a-zA-Z@_数字一样)。

有了kshzsh,还有:

$ typeset -i34 x=123; echo "$x"
34#3l

尽管 ksh88、zsh 和 pdksh 中的碱基数最多为 36 个,ksh93 中的碱基数最多为 64 个。

long请注意,所有这些都仅限于系统上整数的大小(int对于某些 shell)。对于更大的东西,您可以使用bcdc

$ echo 'obase=16; 9999999999999999999999' | bc
21E19E0C9BAB23FFFFF
$ echo '16o 9999999999999999999999 p' | dc
21E19E0C9BAB23FFFFF

支持的基数范围从 2 到 POSIX 要求的至少为 99 的某个数字。对于大于 16 的基数,大于 9 的数字表示为以空格分隔的 0 填充的十进制数。

$ echo 'obase=30; 123456' | bc
 04 17 05 06

或者与dcbc曾经是(并且仍然在某些系统上)包装器相同dc):

$ echo 30o123456p | dc
 04 17 05 06

答案2

使用 printf:

$ printf "%d %x\n" $((16#55)) $((10#85))
85 55

要将值分配给变量,请使用命令替换:

$ x=$( printf "%x" 85 ) ; echo $x
55

答案3

使用所有 POSIX 兼容 shell 中存在的内置算术扩展替换 - 这在当今几乎是普遍的。

$ echo $((0xbc))
188

$ hex=dead
$ dec=$((0x$hex))
$ echo $dec
57005

注意:特别是在最后一个示例中,扩展可能会导致意外结果 - 变量“hex”中的十六进制数字必须形成合法的十六进制常量,否则可能会发生模糊的错误消息。例如,如果“hex”为“0xdead”,则算术扩展将变为 0x0xdead,这不能解释为常量。当然,在这种情况下,算术扩展 $(($hex)) 就可以解决问题。留给读者的练习是创建简单的子字符串处理模式匹配,以删除可选的“0x”前缀。

答案4

您可以使用 awk丝绒库:

$ velour -n 'print n_baseconv(15, 10, 16)'
F

或者:

$ velour -n 'print n_baseconv(ARGV[1], 10, 16)' 15
F

相关内容