根据$ man gawk
,该strtonum()
函数可以将字符串转换为数字:
strtonum(str)
检查 str,并返回其数值。如果 str 以前导 0 开头,则将其视为八进制数。如果 str 以前导 0x 或 0X 开头,则将其视为十六进制数。否则,假设它是一个十进制数。
如果字符串以 开头0
,则该数字被视为八进制,而如果它以它开头,0x
则被视为十六进制。
我已经运行了这些命令来检查我对函数的理解:
$ awk 'END { print strtonum("0123") }' <<<''
83
$ awk 'END { print strtonum("0x123") }' <<<''
291
该字符串"0123"
被正确地视为包含八进制数并转换为十进制数83
。同样,字符串"0x123"
被正确地视为包含十六进制数并转换为十进制数291
。
现在,如果我运行相同的命令,但将数字字符串从程序文本移动到输入数据,会发生以下情况:
$ awk 'END { print strtonum($1) }' <<<'0123'
123
$ awk 'END { print strtonum($1) }' <<<'0x123'
291
我理解与前面命令相同的第二个结果,但我不理解第一个。为什么 gawk 现在将0123
其视为十进制数,即使它以0
八进制数的前导开头?
我怀疑它与strnum 属性有关,因为出于某种原因1,gawk 将此属性赋予0123
但不赋予0x123
:
$ awk 'END { print typeof($1) }' <<<'0123'
strnum
$ awk 'END { print typeof($1) }' <<<'0x123'
string
1这可能是由于awk 实现之间的差异:
澄清一下,只有来自几个来源的字符串(这里引用 POSIX 规范): [...] 如果它们的值恰好是数字(允许前导和尾随空格, 实现之间有所不同),则将被视为数字字符串支持十六进制,八进制,inf,nan ...)。
我正在使用 gawk version 4.2.62
,输出$ awk -V
为:
GNU Awk 4.2.62, API: 2.0 (GNU MPFR 3.1.4, GNU MP 6.1.0)
这与
strnum
GAWK 4.2 版中的通用处理有关。看起来像数字的输入值被视为
strnum
值,在内部表示为同时具有字符串和数字类型。“0123”看起来像一个数字,所以它被处理为strnum
.strtonum
旨在处理字符串和数字输入;它首先查找数字,当遇到输入数字时,不经转换返回数字:因此“0123”变成了数字123,并
strtonum
直接返回。“0x123” 看起来不像一个数字(根据上面给出的链接中定义的规则),因此它被作为字符串处理并按照您所期望的那样处理
strtonum
。一个数字在 AWK中定义如下: