使用AWK与多个参数比较2个文件

时间:2014-08-07 16:21:08

标签: bash awk

使用awk比较2个文本文件时遇到问题。这就是我想要做的。

File1在第一列中包含一个名称,该名称必须与file2第一列中的名称匹配。这很容易 - 到目前为止一切都很好。然后如果匹配,我需要检查file1的第2列中的数字是否位于file2的第2列和第3列的数值范围内(参见示例)。如果是这种情况,则将匹配的行作为一行打印到新文件。我在awk中写了一些东西,它给了我一个正确分配的输出,但它错过了大多数。我错过了某种循环功能吗?文件都根据第一列进行排序。

File1中:

scaffold10|   300   T   C   0.9695   0.0000
scaffold10|   456   T   A   1.0000   0.0000
scaffold10|   470   C   A   0.9906   0.0000
scaffold10|   600   T   C   0.8423   0.0000
scaffold56|   5     A   C   0.8423   0.0000
scaffold56|   1000  C   T   0.8423   0.0000
scaffold56|   6000  C   C   0.7518   0.0000
scaffold7|    2     T   T   0.9046   0.0000
scaffold9|    300   T   T   0.9034   0.0000
scaffold9|    10900 T   G   0.9044   0.0000

文件2:

scaffold10|   400   550   
scaffold10|   700   800    
scaffold56|   3     5000  
scaffold7|    55    200  
scaffold7|    214   567   
scaffold7|    656   800  
scaffold9|    234   675  
scaffold9|    699   1254 
scaffold9|    10887 11000   

输出:

scaffold10|  456   T   A   1.0000   0.0000   scaffold10|  400   550
scaffold10|  470   C   A   0.9906   0.0000   scaffold10|  400   550
scaffold56|  5     A   C   0.8423   0.0000   scaffold56|  3     5000
scaffold56|  1000  C   T   0.8423   0.0000   scaffold56|  3     5000
scaffold9|   300   T   T   0.9034   0.0000   scaffold9|   234   675 
scaffold9|   10900 T   G   0.9044   0.0000   scaffold9|   10887 11000 

我的尝试:

awk -F "\t" ' FNR==NR {b[$1]=$0; c[$1]=$1; d[$1]=$2; e[$1]=$3; next} for {if (c[$1]==$1 && d[$1]<=$2 && e[$1]>=$2) {print b[$1]"\t"$0}}' File1 File2 > out.txt

如何使用awk获取我想要的输出?任何建议都非常受欢迎......

2 个答案:

答案 0 :(得分:2)

使用join对这两个文件进行数据库样式连接,然后使用AWK过滤掉不正确的匹配项:

$ join file1 file2 | awk '$2 >= $7 && $2 <= $8'
scaffold10| 456 T A 1.0000 0.0000 400 550
scaffold10| 470 C A 0.9906 0.0000 400 550
scaffold56| 5 A C 0.8423 0.0000 3 5000
scaffold56| 1000 C T 0.8423 0.0000 3 5000
scaffold9| 300 T T 0.9034 0.0000 234 675
scaffold9| 10900 T G 0.9044 0.0000 10887 11000

或者,如果您希望输出的格式与您给出的示例中的格式相同:

$ join file1 file2 | awk '$2 >= $7 && $2 <= $8 { printf("%-12s %-5s %-3s %-3s %-8s %-8s %-12s %-5s %-5s\n", $1, $2, $3, $4, $5, $6, $1, $7, $8); }'
scaffold10|  456   T   A   1.0000   0.0000   scaffold10|  400   550
scaffold10|  470   C   A   0.9906   0.0000   scaffold10|  400   550
scaffold56|  5     A   C   0.8423   0.0000   scaffold56|  3     5000
scaffold56|  1000  C   T   0.8423   0.0000   scaffold56|  3     5000
scaffold9|   300   T   T   0.9034   0.0000   scaffold9|   234   675
scaffold9|   10900 T   G   0.9044   0.0000   scaffold9|   10887 11000

答案 1 :(得分:0)

awk 解决方案,将第一个文件读入一个数组,然后将其与第二个文件的内容进行动态比较。

awk 'NR==FNR{i++; x[i]=$0; x_1[i]=$2; x_2[i]=$3 }
     NR!=FNR{ for(j=1;j<=i;j++){
                if( $1~x[j] && x_1[j]<$2 && x_2[j]>$2 ){
                  print $0,x[j]
                }
              }
}' file2 file1

# scaffold10|   456   T   A   1.0000   0.0000 scaffold10|   400   550   
# scaffold10|   470   C   A   0.9906   0.0000 scaffold10|   400   550   
# scaffold56|   5     A   C   0.8423   0.0000 scaffold56|   3     5000  
# scaffold56|   1000  C   T   0.8423   0.0000 scaffold56|   3     5000  
# scaffold9|    300   T   T   0.9034   0.0000 scaffold9|    234   675  
# scaffold9|    10900 T   G   0.9044   0.0000 scaffold9|    10887 11000