我试图在看起来像这样的文件中跳过零除。对于col1中的每个元素,将col3和col4中的值相加,然后除以sumcol3 / sumcol4。
A 3 0.100000 0.200000
A 4 0.100000 0.200000
B 1 0.200000 0.200000
B 5 0.200000 0.000000
C 3 0.200000 0.200000
X 3 0.000000 0.000000
X 5 0.200000 0.200000
D 100 0.00000 0.200000
适应以下代码
# set fields delimiters
BEGIN { FS = OFS = "\t" }
# the first time col1 value occurs, store other cols
!h[$1] {
h[$1] = ++n # save ordering
d[n] = $1 OFS $2
}
# store sums
{
i = h[$1] # recover ordering
a[i] += $3
b[i] += $4
}
# output cols and the computed values
END {
for (i=1; i<=n; i++) {if (b[i]!="0.000000") {print d[i], a[i], b[i], a[i]/b[i]}}
}
但是我仍然被零除
所需的输出将是
A 3 0.200000 0.400000 0.500000
B 1 0.400000 0.200000 0.200000
C 3 0.200000 0.200000 0.100000
X 3 0.200000 0.200000 0.100000
答案 0 :(得分:2)
在awk中,在算术上下文中求值为零的表达式始终被视为0
1 。也就是说,当b[i]
的值为零时,
b[i] != "0.000000"
与以下相同:
0 != "0.000000"
如果将其评估为true
,这将是模棱两可的。因此,您应该使用b[i]!=0
或完全放弃!="0.000000"
2 。
1 尝试运行以下命令:
awk 'BEGIN{print 0.0 + 0.000000 + 0}'
2 在awk和许多其他脚本/编程语言中,在布尔上下文中,计算结果为非零值的表达式的结果为true
。因此,当b[i]!=0
保留数值时,b[i]
和b[i]
是相同的。
答案 1 :(得分:1)
我没有测试过它,因为您的示例输入文件不正确(例如-> $ 19不存在)。恕我直言,我会采取这种方法。我添加了一条警告声明以在输出中获得警告,如果不需要它,可以将其删除。
您可以将for
循环行更改为跟随行。
for (i=1; i<=n; i++) {printf("%d %d %d %d\n",d[i], a[i], b[i], b[i]!=0?a[i]/b[i]:"Warn: There was an attempt to divide by zero")}