awk 合并 col 值在范围内的文件

问题描述 投票:0回答:1

我有一个选项卡 delim dataset1

NC_044998.1     14582   80739   LOC100221041
NC_044998.1     31388   68748   DCBLD2
NC_044998.1     80874   299341  CMSS1
NC_044998.1     112495  297570  FILIP1L
NC_044998.1     287349  289742  LOC116808959
NC_044998.1     300404  343805  TBC1D23
NC_044998.1     333622  344667  NIT2
NC_044998.1     346168  368957  TOMM70
NC_044998.1     371654  380427  LNP1
NC_044998.1     387231  413422  TMEM45A

和另一个选项卡 delim dataset2

1       NC_044998.1     15001   6.040368        2.038993e-04
1       NC_044998.1     25002   0.000000        3.333334e-01
1       NC_044998.1     35003   2.309260        4.638924e-03
1       NC_044998.1     45004   3.438428        5.053365e-03
1       NC_044998.1     55005   1.086369        9.663565e-02
1       NC_044998.1     65006   3.250019        8.298793e-04
1       NC_044998.1     75007   1.081163        8.039542e-03
1       NC_044998.1     85008   0.186722        8.158607e-02
1       NC_044998.1     95009   2.236803        3.256445e-03
1       NC_044998.1     105010  0.089978        2.846438e-01

我想对数据集2的每一行执行以下操作:如果数据集2的第2列中的字符串与数据集1的第1列中的字符串匹配,并且数据集2的第3列中的值在数据集1的第2列和第3列中的值之间,则打印数据集2的行,然后打印数据集1的行, else 打印 dataset2 的行,后跟“.”在每一列中。

我正在使用

NR==FNR {
    q[++n] = $0
    f1[n] = $2
    f2[n] = $3
    next
}
# process file2
{
    for (i = 1; i <= n; i++) {
        if ($1 == f1[i] && (f2[i] > $2 && f2[i] < $3))
            print q[i]"\t"$0
        else
            print q[i]"\t"".""\t"".""\t"".""\t""."
    }
} 

但它不起作用,因为它只打印第一个文件,后跟点列

awk -f annot.sh dataset2 dataset1

1       NC_044998.1     15001   6.040368        2.038993e-04    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     25002   0.000000        3.333334e-01    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     35003   2.309260        4.638924e-03    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     45004   3.438428        5.053365e-03    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     55005   1.086369        9.663565e-02    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     65006   3.250019        8.298793e-04    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     75007   1.081163        8.039542e-03    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     85008   0.186722        8.158607e-02    .       .       .       .       .
1       NC_044998.1     95009   2.236803        3.256445e-03    .       .       .       .       .
1       NC_044998.1     105010  0.089978        2.846438e-01    .       .       .       .       .

输出应该是

1       NC_044998.1     15001   6.040368        2.038993e-04    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     25002   0.000000        3.333334e-01    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     35003   2.309260        4.638924e-03    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     45004   3.438428        5.053365e-03    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     55005   1.086369        9.663565e-02    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     65006   3.250019        8.298793e-04    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     75007   1.081163        8.039542e-03    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     85008   0.186722        8.158607e-02    NC_044998.1     80874   299341  CMSS1
1       NC_044998.1     95009   2.236803        3.256445e-03    NC_044998.1     80874   299341  CMSS1
1       NC_044998.1     105010  0.089978        2.846438e-01    NC_044998.1     80874   299341  CMSS1
awk bioinformatics bed
1个回答
1
投票

假设/理解:

  • 对于
    NC_044998.1
    中的给定键(例如,
    dataset1
    )可以有多行,其中一些行的范围($2 - $3)重叠
  • 由于范围重叠 (
    dataset1
    ),我假设
    dataset2
    中的一行有可能从
    dataset1
    中找到多个匹配项;事实上,有几个这样的实例,但 OP 的预期输出没有显示双重匹配(现在我假设 OP 需要更新预期输出或提供更多详细信息,说明当
    dataset2
    中的一行有更多匹配项时该怎么做)超过一场比赛
    dataset1
    )

我将以下行添加到

dataset2
,以演示
dataset1
中的不匹配:

1       NC_044998.1     999999  0.089978        2.846438e-01

使用

GNU awk
的一个想法:

$ cat dataset.awk
BEGIN   { OFS = "\t"
          delete range                                             # explicitly inform awk
          delete desc                                              # these are arrays
        }

        # process 1st file (dataset1)

NR==FNR { range[$1][$2]=$3                                         # $1==key(NC_044998.1), $2==low, $3==high
          desc[$1][$2]=$4                                          # $4==description
          next
        }

        # process 2nd file (dataset2)

        { found_match = 0
          if ( $2 in range )
             for ( low in range[$2] )
                 if ( low <= $3+0 && $3 <= range[$2][low] ) {      # "+0" used for force awk to treat value as a number and not a string
                    found_match = 1
                    print $0,$2,low,range[$2][low],desc[$2][low]
                 }
             if ( found_match == 0 )
                print $0,".",".",".",".","."
        }

注意事项:

  • 多维数组支持需要
    GNU awk
  • 多维数组可能会耗尽“额外”内存,因此我假设 OP 的数据集不会大到导致
    awk
    生成内存不足错误

试驾:

$ awk -f dataset.awk dataset1 dataset2
1       NC_044998.1     15001   6.040368        2.038993e-04    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     25002   0.000000        3.333334e-01    NC_044998.1     14582   80739   LOC100221041

1       NC_044998.1     35003   2.309260        4.638924e-03    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     35003   2.309260        4.638924e-03    NC_044998.1     31388   68748   DCBLD2

1       NC_044998.1     45004   3.438428        5.053365e-03    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     45004   3.438428        5.053365e-03    NC_044998.1     31388   68748   DCBLD2

1       NC_044998.1     55005   1.086369        9.663565e-02    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     55005   1.086369        9.663565e-02    NC_044998.1     31388   68748   DCBLD2

1       NC_044998.1     65006   3.250019        8.298793e-04    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     65006   3.250019        8.298793e-04    NC_044998.1     31388   68748   DCBLD2

1       NC_044998.1     75007   1.081163        8.039542e-03    NC_044998.1     14582   80739   LOC100221041
1       NC_044998.1     85008   0.186722        8.158607e-02    NC_044998.1     80874   299341  CMSS1
1       NC_044998.1     95009   2.236803        3.256445e-03    NC_044998.1     80874   299341  CMSS1
1       NC_044998.1     105010  0.089978        2.846438e-01    NC_044998.1     80874   299341  CMSS1
1       NC_044998.1     999999  0.089978        2.846438e-01    .       .       .       .       .

注意:

    为了清楚起见,添加了
  • 空行,以显示
    dataset2
    中的一行与
    dataset1
  • 中的多个匹配项的情况
© www.soinside.com 2019 - 2024. All rights reserved.