您在这里处理两个相似但不同的问题,awk
输入中的非十进制数据和程序中的非十进制文字awk
。
请参阅POSIX-1.2004 awk 规范,词汇约定:
8. The token NUMBER shall represent a numeric constant. Its form and numeric value [...]
with the following exceptions:
a. An integer constant cannot begin with 0x or include the hexadecimal digits 'a', [...]
所以 awk (大概你正在使用nawk
or mawk
)表现得“正确”。gawk
(从 3.1 版开始)默认支持非十进制(八进制和十六进制)文字数字,尽管使用--posix
开关将其关闭,如预期的那样。
在这种情况下,正常的解决方法是使用定义的数字字符串行为,其中数字字符串将被有效地解析为支持-prefixed 数字的 C 标准atof()
或strtod()
函数:0x
$ echo "0x14" | nawk '$1+1<=0x15 {print $1+1}'
<no output>
$ echo "0x14" | nawk '$1+1<=("0x15"+0) {print $1+1}'
21
这里的问题是这并不完全正确,因为POSIX-1.2004 还指出:
A string value shall be considered a numeric string if it comes from one of the following:
1. Field variables
...
and after all the following conversions have been applied, the resulting string would
lexically be recognized as a NUMBER token as described by the lexical conventions in Grammar
更新:gawk
针对“2008 POSIX.1003.1”,但请注意,因为 2008 版(请参阅此处的IEEE Std 1003.1 2013 版awk
)允许strtod()
和实现相关的行为,不需要数字符合词汇约定。INF
这也应该(隐式)支持NAN
。Lexical Conventions中的文本进行了类似的修改,以选择性地允许带0x
前缀的十六进制常量。
这不会像希望的那样表现(考虑到对数字的词法约束)gawk
:
$ echo "0x14" | gawk '$1+1<=0x15 {print $1+1}'
1
(注意“错误”的数字答案,它会被 隐藏|wc -l
)除非你也使用--non-decimal-data
:
$ echo "0x14" | gawk --non-decimal-data '$1+1<=0x15 {print $1+1}'
21
也可以看看:
此SE 问题的公认答案具有可移植性解决方法。
对非十进制数提供两种类型的支持的选项是:
- 仅使用
gawk
,不使用--posix
和使用--non-numeric-data
- 实现一个包装函数来执行十六进制到十进制,并将其与您的文字和输入数据一起使用
如果您搜索“awk dec2hex”,您可以找到后者的许多实例,一个可以通过的实例在这里:http ://www.tek-tips.com/viewthread.cfm?qid=1352504 。如果你想要 gawk 之类的东西,你可以在这里strtonum()
得到一个可移植的 awk-only 版本。