如何使用bash

时间:2019-07-14 15:04:55

标签: linux bash awk

我正在尝试对第一列中具有共享的 substring 的行的数据框各行的值求和。数据如下:

ID Data_1 Data_2 Data_3 Data_4 
SRW8002300_T01 1 2 3 4
SRW8002300_T02 1 2 3 4
SRW8002300_T03 1 2 3 4
SRW8004500_T01 1 2 3 4
SRW8004500_T02 1 2 3 4
SRW8006000_T01 1 2 3 4

当ID的第一部分(下划线之前的部分)共享时,我想对第二至第五列的值求和。因此,以上内容将变为:

ID Data_1 Data_2 Data_3 Data_4 
SRW8002300 3 6 9 12
SRW8004500 2 4 6 8
SRW8006000 1 2 3 4

到目前为止,我已经有了一个awk命令,该命令可以在下划线后去除字符串的ID:

awk '{print $1}' filename | awk -F'_' '{print $1}'

如果共享第一列中的值,则另外一个用于对列值求和:

awk '{a[$1]+=$2;b[$1]+=$3;c[$1]+=$4;d[$1]+=$5} END {for (i in a) print i, a[i], b[i], c[i], d[i]}' filename

但是,我正在努力将这两个命令结合起来以创建一个具有共享ID的总和的新数据框。

我通常使用python编写代码,但正设法养成为这类任务编写bash脚本的习惯。

谢谢您的帮助。

1 个答案:

答案 0 :(得分:1)

假设您的键值是连续的,如示例输入中所示:

$ cat tst.awk
NR==1 { print; next }
{
    curr = $1
    sub(/_.*/,"",curr)

    if ( curr != prev ) {
        prt()
    }

    for (i=2; i<=NF; i++) {
        sum[i] += $i
    }

    prev = curr
}

END { prt() }

function prt() {
    if ( prev != "" ) {
        printf "%s%s", prev, OFS
        for (i=2; i<=NF; i++) {
            printf "%d%s", sum[i], (i<NF ? OFS : ORS)
        }
        delete sum
    }
}

$ awk -f tst.awk file
ID Data_1 Data_2 Data_3 Data_4
SRW8002300 3 6 9 12
SRW8004500 2 4 6 8
SRW8006000 1 2 3 4