首页 > 解决方案 > 使用 awk 根据第二个文件从一个文件中排除一系列行

问题描述

我有两个文件 - 文件一个在第 1 列中包含一个数字 (1-22) 以及一个从较低数字 (第 2 列) 到较高数字 (第 3 列) 的范围。这是前几行:

1 11362778 12362778
1 22054176 23054176
1 28191734 29191734
1 42956767 43956767
1 65941329 66941329

第一个文件没有任何标题。

在第二个文件中,我有很多列,第一个显示在这里:

单核苷酸多态性 CHR 英国石油公司
rs115828134 1 11363041
rs2788537 1 11363231
rs12141932 1 11363301

如果文件 2 中的第 2 列等于文件 1 中的第 1 列并且如果文件 2 中的第 3 列在文件 2 中的第 2 列和第 3 列的范围内,我想要做的是删除文件 2 中的所有行。

本质上是这样的:但是循环遍历文件 1 的所有行。

awk '{if($2==1 && $3 < 11362778 || $3 > 12362778) print $0}' file 2 > results.txt 

标签: awk

解决方案


我 100% 同意 @jared_mamrot,为此使用适当的生物信息工具。

然而,有一种方法可以使用awk来解决这个问题。但是一定要在真正的数据集上进行测试,然后再依赖它进行严肃的科学,因为我不完全确定它是否涵盖所有极端情况,尤其是你的有限示例。

数据(添加匹配数据):

$ cat file1
1       11362778        12362778
1       22054176        23054176
1       28191734        29191734
1       42956767        43956767
1       65941329        66941329
2       42956767        43956767
2       65941329        66941329

$ cat file2
SNP     CHR     BP
rs10875231      1       100000012
rs6678176       1       100000827
rs78286437      1       100000843
rr234233        1       29000000
rr453654        1       29000120
e34534534       1       23444444
rs144406489     1       100001138
rr564564        2       29000120
e34534534       2       23444444
rs144406489     2       42956775 

利用:

$ awk 'NR==FNR{ chr[NR]=$1; x[NR]=$2; y[NR]=$3; en=NR }
       NR!=FNR{ set=0;
                for(i=1;i<=en;i++){
                  if(chr[i]==$2 && ( $3 <= y[i] && $3 >= x[i] ) ){
                    set=0; break
                  }
                  else{ set=1 }
                }
                if(set==1){ print }
      }' file1 file2

输出:

SNP     CHR     BP
rs10875231      1       100000012
rs6678176       1       100000827
rs78286437      1       100000843
e34534534       1       23444444
rs144406489     1       100001138
rr564564        2       29000120
e34534534       2       23444444 

推荐阅读