我有这个代码:
awk '!seen[$1,$2]++{a[$1]=(a[$1] ? a[$1]", " : "\t") $2} END{for (i in a) print i a[i]} ' inputfile
我想折叠包含两个以上字段的行,但始终基于第一个字段作为索引。
输入文件(三列制表符分隔):
protein_1 membrane 1e-4
protein_1 intracellular 1e-5
protein_2 membrane 1e-50
protein_2 citosol 1e-40
所需的输出(三列制表符分隔):
protein_1 membrane, intracellular 1e-4, 1e-5
protein_2 membrane, citosol 1e-50, 1e-40
谢谢!
堆栈在这里:
awk '!seen[$1,$2]++{a[$1]=(a[$1] ? a[$1]"\t" : "\t") $2};{a[$1]=(a[$1] ? a[$1]", " : "\t") $3} END{for (i in a) print i a[i]} ' 1 inputfile
最佳答案
我真的希望有人发布一些 awk 魔法,但我现在会继续扔掉更长的 perl 脚本:
use strict;
use warnings;
my @cols = ();
my $lastprotein = '';
while (<DATA>) {
chomp;
my ($protein, @data) = split "\t";
if ($protein ne $lastprotein && @cols) {
print join("\t", $lastprotein, map {join ', ', @$_} @cols), "\n";
@cols = ();
}
push @{$cols[$_]}, $data[$_] for (0..$#data);
$lastprotein = $protein;
}
print join("\t", $lastprotein, map {join ', ', @$_} @cols), "\n";
__DATA__
protein_1 membrane 1e-4
protein_1 intracellular 1e-5
protein_2 membrane 1e-50
protein_2 citosol 1e-40
输出
protein_1 membrane, intracellular 1e-4, 1e-5
protein_2 membrane, citosol 1e-50, 1e-40
关于perl - 折叠具有多个字段的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22307750/