我想对重复的行进行分组,并从这些行中减去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]};打印s}}''但是将+ =更改为-=不会减去,它仍然是值的总和,但在前面加上减号。
谢谢。
答案 0 :(得分:1)
$ 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
答案 1 :(得分:0)
如果不必awk,此perl脚本将为您的示例输入提供所需的输出:
#!/usr/bin/perl
use warnings;
use strict;
use feature qw/say/;
use List::MoreUtils qw/pairwise/; # Non-core; install through your OS or CPAN.
my %records;
while (<>) {
my ($key, @cols) = split /\s+/;
$records{$key} =
[ pairwise { defined $a ? $a - ($b // 0) : $b } @{$records{$key}}, @cols ];
}
foreach my $key (sort keys %records) {
say "$key @{$records{$key}}";
}
它会像您的示例一样按排序顺序生成输出。如果行应该按照它们第一次出现在实际输入中的顺序排列,那也是可行的。您的样本尚不清楚,因为该样本开始排序。
它也不要求重复是连续的-重要吗?