如果语句跳过零除

时间:2019-09-01 23:49:25

标签: awk

我试图在看起来像这样的文件中跳过零除。对于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

2 个答案:

答案 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")}