我有一个对文件中的列求和的程序:
awk -v col=2 '{sum+=$col}END{print sum}' input-file
但是,它有一个问题:如果您给它一个没有数字数据的文件,(或者如果缺少一个数字)它会将其解释为零。
如果其中一个字段无法解析为数字,我希望它产生错误。
这是一个示例输入:
bob 1
dave 2
alice 3.5
foo bar
我希望它产生错误,因为“bar”不是数字,而不是忽略错误。
我有一个对文件中的列求和的程序:
awk -v col=2 '{sum+=$col}END{print sum}' input-file
但是,它有一个问题:如果您给它一个没有数字数据的文件,(或者如果缺少一个数字)它会将其解释为零。
如果其中一个字段无法解析为数字,我希望它产生错误。
这是一个示例输入:
bob 1
dave 2
alice 3.5
foo bar
我希望它产生错误,因为“bar”不是数字,而不是忽略错误。
一种合理的测试方法是使用类似于 的测试来比较字段
strtod
,这是awk 用来将字符串转换为数字的方法:以上与 strtod 的不同之处在于它不将 INFINITY 或 NAN 视为“数字”。在 awk 的默认字段拆分行为下,可以放宽前导空格的要求——这意味着字段永远不会包含前导空格:
感谢 Stéphane 的评论和回答,进一步完善:
打破了稍微更好的易读性,该正则表达式是:
...其目的是允许可能的前导 + 或 -,然后是浮点数或十六进制数。浮点数具有可选的前导数字、选项分隔符(这里固定为句
.
点),后跟一些数字,可选地后跟一个指数。十六进制数必须以0x
or开头0X
,后跟十六进制数字、分隔符、更多十六进制数字,并且可以选择后跟“幂”(指数)。整个第二个字段必须匹配其中一种格式(由^
和锚定$
)。出于本问题的目的,此处省略了 NAN 和 INFINITY 选项。另一种选择是强制进行数字转换,然后将其与零进行比较,然后进一步将原始输入与将转换为零的内容进行比较;更具体地说,它是以可选的 + 或 - 开头,然后是零,还是后跟一个句点和零:
我最终得到了这个:
这使用 typeof,它是一个 GNU awk 扩展。如果是有效数字,
typeof($col)
则返回 'strnum',否则返回 ' string' 或 'unassigned'。$col
请参阅 我可以确定 awk 变量的类型吗?
如果您希望它也可以处理
.0
或.0e+33
作为0
;的有效表示,则由您来复杂化 请注意,awk
将字符串转换为数字时将忽略尾随垃圾("1.4e1e3"+0
,"1.4e1.e7"+0
或"14+13"+0
将全部等于 14)。解释只是使用正则表达式来检查字符的存在,这些字符不是数字也不是浮点数、符号等。
添加
或者
到规则。
或者,您可以比较
NF
它是否是您示例中的最后一列。