Awk If语句跳过零除

Awk If语句跳过零除,awk,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 #

我正试图在一个类似这样的文件中跳过零除法。对于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]}}
}
调整以下代码

# 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]}}
}

在awk中,在算术上下文中计算为零的表达式总是被视为
0
1。也就是说,当
b[i]
的值为零时

# 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]}}
}
b[i] != "0.000000"
同:

# 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]}}
}
0 != "0.000000"
如果计算结果为
true
,则不明确。因此,您应该使用
b[i]=0或删除
=“0.000000”
2

# 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]}}
}

1尝试运行以下命令:

# 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]}}
}
awk 'BEGIN{print 0.0 + 0.000000 + 0}'

2在awk和许多其他脚本/编程语言中,计算为非零值的表达式在布尔上下文中计算为
true
。所以,
b[i]=当
b[i]
持有一个数值时,0和
b[i]
是相同的。

我没有测试它,因为您的样本不是正确的输入文件(例如-->$19不在那里)。我想我会采取这种方法。我已经添加了一个警告语句来获取输出中的警告,如果您不需要它,可以将其删除

# 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]}}
}
您可以将
循环行更改为以下内容

# 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]}}
}
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")}

for(i=1;iIt似乎有效。我不明白。为什么只说如果(b[i])有效呢?Thnxs!你正在用字符串比较一个数字。这永远是真的。为了代码的清晰,你应该写
b[i]!=0
。如果(b[i])
,你可以写
,但这会让你的代码更难读(一周后你就会忘记它的意思)。