首页 > 解决方案 > awk 减去不同的列

问题描述

我想对重复的行进行分组并从这些行中减去 cols 中的值。知道我该怎么做吗?

例子:

dbstat 100 90 80 60 1000 
dbstat 10 10 10 20 
test 5 5
output should be: 
dbstat 90 80 70 40 1000 
test 5 5

更新:对于其他文件,我必须对匹配行的值求和,这可以很好地使用:

awk '{for (i=2;i<=NF;i++) {a[$1][i]+=$i}} END{ for (j in a) {s=j; 对于 (i=2;i<=NF;i++) {s=s" "a[j][i]}; 印刷}}'

但是将 += 更改为 -= 不会减去,它仍然会对值进行求和,但会在前面加上减号。

谢谢你。

标签: linuxawk

解决方案


$ cat file
test1 100 20 25 30
test1 10 10
test1 30 0 2
test2 500
test2 100 50 90
test2 10 0
test3 100 100 100
$
$ cat tst.awk
p != $1 {
    for (i in c)
        p = p OFS c[i]
    if (p)
        print p
    p = $1
    delete c
    for (i = 2; i <= NF; ++i)
        c[i] = $i
    next
}
{
    for (i = 2; i <= NF; ++i)
        c[i] -= $i
}
END {
    for (i in c)
        p = p OFS c[i]
    print p
}
$
$ awk -f tst.awk file
test1 60 10 23 30
test2 390 -50 -90
test3 100 100 100

如果没有对重复的列进行分组:

$ cat file2
test2 500
test1 100 20 25 30
test2 100 50 90
test1 30 0 2
test2 10 0
test3 100 100 100
test1 10 10
$
$ cat tst2.awk
{
    f = ($1 in a)
    for (i = 2; i <= NF; ++i)
        a[$1][i] -= (f ? $i : -$i)
}
END {
    for (k in a) {
        o = k
        for (i in a[k])
            o = o OFS a[k][i]
        print o
    }
}
$
$ awk -f tst2.awk file2
test1 60 10 23 30
test2 390 -50 -90
test3 100 100 100

推荐阅读