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


29

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

$ echo $((16#55))
85

通过网络搜索,我发现了一个脚本,该脚本可以进行数学和字符操作来进行转换,并且可以将其用作函数,但是我以为bash已经具有内置的基本转换-可以?


Answers:


35

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

printf '%x\n' 85

有了zsh,您还可以执行以下操作:

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

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

使用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

谢谢。正是我想要的。(而且非常简单。)
Dave Rove 2015年

如果您想做一个可以指定的任意基数怎么办#
flarn2006年

@ flarn2006。使用bash内建函数,您可以以任何基数输入数字,但不能以8、10和16以外的任何基数输出数字。对于其他基数,则需要另一个shell,例如zshor ksh或use bc/dc
斯特凡Chazelas

1
@StéphaneChazelas真的吗?有点奇怪 似乎他们似乎太懒了,无法为其编写语法。如果他们实现了输入,那么在任何基础上进行输出的想法都不会出现。
flarn2006 '16

alias hex="printf '%x\n'"
mwfearnley

5

使用printf:

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

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

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

4
或者,使用-v内置printf 的选项:printf -v foo "%d" $((16#BEEF)); echo $foo
glenn jackman

@Glenn -v这里不需要使用非标准选项(例如);我会避免的。
Janis

3
-v将避免使用分叉和管道(在bash中,而不是在ksh93中,它不会像printf内置的那样在此处分叉)。请注意,这$((16#55))也不是标准的。
斯特凡Chazelas

@StéphaneChazelas,请稍等。您是说ksh93不适合x=$(some_builtin)吗?
格伦·杰克曼(Glenn Jackman)2015年

1
@glennjackman,是的,它只是派生用于执行外部命令。
斯特凡Chazelas

2

使用所有POSIX兼容外壳程序中都存在的内置算术扩展替换-目前这已经很普遍了。

$ echo $((0xbc))
188

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

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


4
您正在执行OP在他的示例中所做的完全相同的操作;他正在寻找反向操作。
Thomas Guyot-Sionnest'2

0

您可以使用awk Velor库

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

要么:

$ velour -n 'print n_baseconv(ARGV[1], 10, 16)' 15
F
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.