从十进制到十六进制的 BASH 基数转换

Dav*_*ove 47 shell bash text-processing hex

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

$ echo $((16#55))
85
Run Code Online (Sandbox Code Playgroud)

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

Sté*_*las 64

使用bash(或任何 shell,只要printf命令可用(通常在 shell 中构建的标准 POSIX 命令):

printf '%x\n' 85
Run Code Online (Sandbox Code Playgroud)

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

dec=85
hex=$(([##16]dec))
Run Code Online (Sandbox Code Playgroud)

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

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

使用ksh93,您可以使用:

dec=85
base54=${ printf %..54 "$dec"; }
Run Code Online (Sandbox Code Playgroud)

适用于 2 到 64 的基数(以0-9a-zA-Z@_数字表示)。

使用kshand zsh,还有:

$ typeset -i34 x=123; echo "$x"
34#3l
Run Code Online (Sandbox Code Playgroud)

尽管这限制在 ksh88、zsh 和 pdksh 中最多 36 个基数以及 ksh93 中最多 64 个基数。

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

$ echo 'obase=16; 9999999999999999999999' | bc
21E19E0C9BAB23FFFFF
$ echo '16o 9999999999999999999999 p' | dc
21E19E0C9BAB23FFFFF
Run Code Online (Sandbox Code Playgroud)

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

$ echo 'obase=30; 123456' | bc
 04 17 05 06
Run Code Online (Sandbox Code Playgroud)

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

$ echo 30o123456p | dc
 04 17 05 06
Run Code Online (Sandbox Code Playgroud)


Jan*_*nis 7

使用printf:

$ printf "%d %x\n" $((16#55)) $((10#85))
85 55
Run Code Online (Sandbox Code Playgroud)

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

$ x=$( printf "%x" 85 ) ; echo $x
55
Run Code Online (Sandbox Code Playgroud)

  • 或者,对内置 printf 使用 `-v` 选项:`printf -v foo "%d" $((16#BEEF)); 回声 $foo` (4认同)
  • `-v` 将避免分叉和管道(在 bash 中,而不是 ksh93,因为 `printf` 是内置的,因此不会在这里分叉)。请注意,`$((16#55))` 也不是标准的。 (3认同)