包含特定术语的行的列总和

包含特定术语的行的列总和

我想知道是否有任何sed命令awk可以对具有相同标识符的行的所有列进行求和。例如,我的文件data.txt如下所示,但它包含约 1800 列数据和约 1400 行。

ABCD:1234  1.23  0.23  0.83   0
ABCD:1234    0    1.10  0.21   0 
EFGH:5678    0    1.90  0.12  8.21
IJKL:9999    1.22  0    1.84  9.21
IJKL:9999    1.44  0   12.94   0
IJKL:9999    1.32  0   24.12   2.43

我希望命令之后的样子是这样的:

ABCD:1234  1.23  1.33  1.04  0
EFGH:5678    0    1.90  0.12  8.21
IJKL:9999   3.98   0   38.9  11.64

我不确定这是否可以用awkor sed(我是一名生物学家,仍在学习 Unix 的基础知识)。任何帮助将非常感激。

答案1

awk不将输入文件或整个结果表保存在内存中的脚本:

FNR == 1   { for(i = 1; i <= NF; i++) a[i] = $i;  next }
$1 == a[1] { for(i = 2; i <= NF; i++) a[i] += $i; next }
{
    printf "%s", a[1]; a[1] = $1;
    for(i = 2; i <= NF; i++) { printf "\t%s", a[i]; a[i] = $i };
    printf "\n";
}
END {
    printf "%s", a[1];
    for(i = 2; i <= NF; i++) printf "\t%s", a[i];
    printf "\n";
}

运行它:

awk -f script.awk data.txt

结果:

ABCD:1234       1.23    1.33    1.04    0
EFGH:5678       0       1.90    0.12    8.21
IJKL:9999       3.98    0       38.9    11.64

附带说明:实际上可以使用sed.但你不会很快这样做。看这里了解原因。

答案2

替代解决方案perl

$ perl -nale '
if(!$seen{$F[0]}++)
{
    print join "\t", @a if @a;
    @a = @F[0..$#F];
}
else
{
    $a[$_] += $F[$_] foreach(1..$#F);
}
print join "\t", @a if eof;
' data.txt 
ABCD:1234   1.23    1.33    1.04    0
EFGH:5678   0       1.90    0.12    8.21
IJKL:9999   3.98    0       38.9    11.64
  • -a按空格分割输入行并将它们保存到@F数组中
  • 行的第一个字段用作哈希变量的键%seen,如果未找到键,则打印@a数组的内容(如果它不为空)并将新行的字段分配给数组
  • 如果键已经存在,则将数组的内容(从第二个字段到末尾)增加到当前行中的相应内容
  • @a要处理最后一个条目,请在到达文件末尾时再次打印数组内容


对于重复的问题:如果第一列有相同的条目,则在 Linux 中分别添加所有列

$ perl -nale '
if(!$seen{$F[0]}++)
{
    print join "\t", @a if @a;
    @a = @F[0..$#F];
}
else
{
    $a[$_] += $F[$_] foreach(1..$#F);
}
print join "\t", @a if eof;
' filename.txt 
AC1481523   6   6   6   6
AC1481676   6   5   6   8


构建数组哈希并在最后打印哈希的解决方案:

$ perl -nale '
if($h{$F[0]})
{
    $h{$F[0]}[$_] += $F[$_] foreach (1..$#F)
}
else
{
    $h{$F[0]} = [@F]
}
END { print join "\t",@{$h{$_}} foreach sort keys %h }
' data.txt
ABCD:1234   1.23    1.33    1.04    0
EFGH:5678   0       1.90    0.12    8.21
IJKL:9999   3.98    0       38.9    11.64

相关内容