将分区和细分(A.1和A.1.1)分配给文件中的数据

时间:2014-08-21 21:47:26

标签: bash awk

我在文件中输入了以下数据。

      start  end
chr1   100   300
chr2   200   400

“开始”和“结束”表示该区域的长度。因此,对于“chr1”,区域长度为200.对于“chr2”,长度为200。 我使用awk'{print$0 "\tA." NR}为每个“chr”区域分配了一个“名称”来生成:

      start  end  name
chr1   100   300  A.1
chr2   200   400  A.2

我接下来要做的是通过将区域长度分成100个来将chr1分成2个部分,并用A.1.1和A.1.2命名每个部分(表示它们曾经是1个部分,但是被分割进入2)。与“chr2”相同。所以他们看起来像这样:

      start end  name
chr1   100  200  A.1.1
chr1   201  300  A.1.2
chr2   200  300  A.2.1
chr2   301  400  A.2.2

所以,我的问题是最后一部分。是否可以使用awk或可以使用awk的东西(因为我已经在第一部分使用awk)来解决这个问题?如果是的话,你会怎么做?

感谢帮助人员。

2 个答案:

答案 0 :(得分:1)

使用以下输入:

chr1   100   300
chr2   200   400

我保持脚本简单,以便您可以按照正在完成的操作。您可以绕过正在执行的中间步骤,因为以下步骤将完成。

awk -v OFS="\t" '
{
    offset = 0;
    range = int(($3-$2)/100);
    start = $2;
    end = $3;
    for (iter=1; iter<=range; iter++) {
        print $1, start+offset, (iter==range?end:start+100), "A."NR"."iter;
        offset = 1;
        start+=100
    }
}' file
chr1    100    200    A.1.1
chr1    201    300    A.1.2
chr2    200    300    A.2.1
chr2    301    400    A.2.2

我们创建了三个变量iterstartend,每个变量都被初始化为0。我们会计算startend的范围。我们循环打印column1,start range,start + 100以及字符A,然后是行号和迭代号。

我们将偏移量初始化为1,以便下一个范围不会从第一个范围开始。

有一个三元测试(iter==range?end:start+100),它基本上会检查我们是否接近范围的末尾。如果我们是,我们使用结束号码。这是为了处理你的行chr1 100 150

的情况

答案 1 :(得分:1)

$ awk '$1!=prev{++cnt} {print $0 "\tA." cnt "." ++seen[$1]; prev=$1}' file
chr1   100  200 A.1.1
chr1   201  300 A.1.2
chr2   200  300 A.2.1
chr2   301  400 A.2.2