【问题标题】:Comparing 2 files using AWK with multiple parameters使用带有多个参数的 AWK 比较 2 个文件
【发布时间】:2014-09-30 23:44:13
【问题描述】:

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

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

文件1:

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 尝试:

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 获得我想要的输出?任何建议都非常欢迎...

【问题讨论】:

  • 那个 awk 脚本有语法错误。 for 在那里无效。话虽如此,您在作业中也错误地折叠了File1 中的多行。您在字段 $1 之外键入 bcde 表,但该字段跨行重复,因此您将只存储给定值的最后一行。
  • 考虑到您的要求,我想您可能会发现反过来操作文件也更容易。即首先捕获范围,然后将File1 中的行与您看到的行进行比较。
  • 感谢 Etan 指出我的错误。

标签: bash awk


【解决方案1】:

使用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

【讨论】:

  • 非常感谢罗斯。有效。你真的帮了我很多!!一个非常聪明的解决方案 =)
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2023-03-27
    • 2019-09-08
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-31
    • 2018-10-23
    相关资源
    最近更新 更多