我们说我有这个制表符分隔的文件
id1 term1 term2
id2 term1 term2
id3 tern2 term3
我想要做的是计算相同column2 column3次出现的次数以及它们引用的ID。
因此新的制表符分隔文件将如下所示:
term1 term2 2 id1,id2
term2 term3 1 id3
我尝试过这种单线,这是我最接近所需解决方案的
awk '{count[$2,$3]++;} END {for (word in count) printf("%s\t%s\n", word,count[word])}'
但我得到的是:
term1 term2 2
term2 term3 1
和术语之间的矩形。
Perl或awk或其他任何想法都很可爱。
起初我认为Perl会更好但是我的朋友建议awk。这是我第一次使用awk。
答案 0 :(得分:2)
此解决方案按您的要求执行
数组@pairs
的唯一目的是保留输入数据的顺序。如果没有必要,那么代码可以大大减少
我假设给定的第2列/第3列值可能会出现多次具有相同ID的值。这意味着我必须将该对的出现次数与累积相关ID分开计算。如果不是这样,则计数只是每对的ID数
use strict;
use warnings;
use feature 'say';
my %pairs;
my @pairs;
while ( <> ) {
chomp;
my ($id, $pair) = split "\t", $_, 2;
push @pairs, $pair unless $pairs{$pair};
++$pairs{$pair}{count};
$pairs{$pair}{ids}{$id} = 1;
}
for my $pair ( @pairs ) {
my ($n, $ids) = @{ $pairs{$pair} }{qw/ count ids /};
say join "\t", $pair, $n, join(',', keys %$ids);
}
term1 term2 2 id1,id2
tern2 term3 1 id3
答案 1 :(得分:1)
您可以使用awk
:
awk -f script.awk input.file
script.awk 的位置如下:
{
# Select and count the terms combination
terms=$2" "$3
count[terms]++
# Concatenate ids by `,` - except if it
# is the first occurrence
ids[terms]=ids[terms] ? ids[terms]","$1 : $1
}
END{
# At the end print the desired results
for(terms in count){
print terms,count[terms],ids[terms]
}
}
答案 2 :(得分:1)
用于真正的2D数组的GNU awk:
$ cat tst.awk
BEGIN { FS=OFS="\t" }
{ ids[$2 FS $3][$1] }
END {
for (key in ids) {
printf "%s\t%s", key, length(ids[key])
sep = OFS
for (i in ids[key]) {
printf "%s%s", sep, i
sep = ","
}
print ""
}
}
$ awk -f tst.awk file
tern2 term3 1 id3
term1 term2 2 id1,id2