Awk:不同列的不同行的总和

时间:2017-04-10 15:35:31

标签: bash awk

说我有输入

num gene    Label   start   end
n1  g1a1    L1  28  40
n1  g1a1    L2  9   42
n1  g1a1    L2  28  90
n1  g1a1    VE  64  209
n1  g1a1    VE  83  377
n1  g1a1    VR  91  377
n1  g1a1    V   378 1516
n1  g1a1    V   475 1613
n1  g1a1    V   1378    2105

n1  g2a1    VE  10209   10590
n1  g2a1    VE  11311   11590
n1  g2a1    VR  11301   11590

n2  g1a2    VE  83  377
n2  g1a2    VR  91  377

n3  g3a1    VR  105200  105801

预期输出

num gene    Label   start   end
n1  g1a1    L1  28  40
n1  g1a1    L2  28  90
n1  g1a1    VE  83  377
n1  g1a1    VR  91  377
n1  g1a1    V   378 1516

n1  g2a1    VE  11311   11590
n1  g2a1    VR  11301   11590

n2  g1a2    VE  83  377
n2  g1a2    VR  91  377

n3  g3a1    VR  105200  105801

我想根据字段$ 3和$ 2比较行 n 和行 n + p 之间的2个数字字段($ 4和$ 5)。

除标签L1外,标签的所有开始和结束位置($ 3)均按基因($ 2)和数字($ 1)与VR开始或结束位置进行比较。

例如对于n1:

if VR(end) = 377 then:
VE(end) = 377
V(start) = VR(end) + 1
L2(start) = VR(start) - 1

Here the schema of all labels gathered

首先,我尝试编写这些awk命令行

  1. 使用带有标签作为键的数组来轻松检索相应标签的起点和终点位置:

    awk' {f [$ 3] = $ 0; for(i = 1; i< = NF; i ++){print i" \ t" $ 1" \ t" $ 2" \ t" $ 3}}' data.txt中

  2. 在当前行中从下一行获取元素:

    awk' NR> 0 {print prev" \ t" $ 3" \ t" $ 4" \ t" $ 5} {prev = $ 0}'输入

  3. 我知道如何从列中提取信息但我几乎不知道从哪里开始为我的比较问题编写awk命令行。

    任何帮助或建议都将受到高度赞赏

    提前致谢

1 个答案:

答案 0 :(得分:0)

你需要按照这些方针做点什么:

/[0-9]/  {
    key = $2 $3
    genes[$2] = 1
    if ($3 == "VR") {
        vr_start[key] = $4
        vr_end[key] = $5
        vr[key] = $0
    } else {
        c = ++count[key]
        start[key c] = $4
        end[key c] = $5
        line[key c] = $0
    }
}
END {
    for (g in genes) {
        gstart = vr_start[g "VR"]
        gend = vr_end[g "VR"]
        c = count[g "L1"]
        for (i = 1; i <= c; i++) {
            print line[g "L1" i]
        }
        c = count[g "L2"]
        for (i = 1; i <= c; i++) {
            if (start[g "L2" i] == gstart - 1) {
                print line[g "L2" i]
            }
        }
        c = count[g "VE"]
        for (i = 1; i <= c; i++) {
            if (end[g "VE" i] == gend) {
                print line[g "VE" i]
            }
        }
        print vr[g "VR"]
        c = count[g "V"]
        for (i = 1; i <= c; i++) {
            if (start[g "V" i] == gend + 1) {
                print line[g "V" i]
            }
        }
    }
}