awk能够将字段解析为十六进制数字:
$ echo "0x14" | awk '{print $1+1}'
21 <-- correct, since 0x14 == 20
Run Code Online (Sandbox Code Playgroud)
但是,它似乎不处理十六进制文字的操作:
$ echo "0x14" | awk '$1+1<=21 {print $1+1}' | wc -l
1 <-- correct
$ echo "0x14" | awk '$1+1<=0x15 {print $1+1}' | wc -l
0 <-- incorrect. awk is not properly handling the 0x15 here
Run Code Online (Sandbox Code Playgroud)
有解决方法吗?
你在这里处理两个相似但不同的问题,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', [...]
Run Code Online (Sandbox Code Playgroud)
所以awk(可能是你正在使用nawk或mawk)表现得"正确".gawk(从版本3.1开始)默认情况下支持非十进制(八进制和十六进制)文字数字,但使用--posix开关会将其关闭,如预期的那样.
这种情况下的正常解决方法是使用定义的数字字符串行为,其中数字字符串有效地被解析为C标准atof()或strtod()函数,它支持0x-prefixed数字:
$ echo "0x14" | nawk '$1+1<=0x15 {print $1+1}'
<no output>
$ echo "0x14" | nawk '$1+1<=("0x15"+0) {print $1+1}'
21
Run Code Online (Sandbox Code Playgroud)
这里的问题是,这不太正确,因为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
Run Code Online (Sandbox Code Playgroud)
更新:gawk针对"2008 POSIX.1003.1",但请注意,自2008版(参见此处的IEEE Std 1003.1 2013版awk)允许strtod()和依赖于实现的行为不需要数字符合词汇约定.这应该(隐含的)支持INF和NAN太.类似地修改了词汇约定中的文本,以选择性地允许带0x前缀的十六进制常量.
这将不会表现出(考虑到对数字的词汇限制),gawk如下所示:
$ echo "0x14" | gawk '$1+1<=0x15 {print $1+1}'
1
Run Code Online (Sandbox Code Playgroud)
(注意是"错误"的数字答案,这将被隐藏的|wc -l),除非你使用--non-decimal-data过:
$ echo "0x14" | gawk --non-decimal-data '$1+1<=0x15 {print $1+1}'
21
Run Code Online (Sandbox Code Playgroud)
也可以看看:
这个SE问题的接受答案有一个可移植性解决方法.
对非十进制数具有两种类型支持的选项是:
gawk,不使用--posix和使用--non-numeric-data如果您搜索"awk dec2hex",您可以找到后者的许多实例,这里有一个可通过的实例:http://www.tek-tips.com/viewthread.cfm?qid = 1352504 .如果你想要像gawk这样的东西strtonum(),你可以在这里获得一个便携式awk专用版本.
| 归档时间: |
|
| 查看次数: |
1005 次 |
| 最近记录: |