2

这是基于较早的问题Awk 条件过滤一个文件基于另一个(或其他解决方案)

问题底部的快速总结

我有一个 awk 程序,如果该行中的值与另一个文本文件中的 3 个值中的 2 个匹配,则从文本文件 'refGene.txt 中的行输出一列。

我需要包含一个额外的标准来查找两个文件之间的匹配项。如果文件 1 中每一行中指定的 2 个数字值的范围与 refGene.txt 中一行中的两个值的范围重叠,则该标准为包含。文件 1 中的一行示例:

chr1 10 20
chr2 10 20

以及匹配列 ($3, $5, $ 6) 的文件 2(refGene.txt) 中的示例行:

chr1 5 30

当前 awk 程序不将此视为匹配项,因为尽管第一列与第二列或第三列都不匹配,但不匹配。但我想要一种将其视为匹配的方法,因为文件 1 中的区域 10-20 在 refGene.txt 中的 5-30 范围内。但是,文件 1 中的第二行不应匹配,因为第一列不匹配,这是必要的。如果有一种方法可以包含文件 1 中的任何范围与 refGene.txt 中的任何范围重叠的情况,这将非常有用(因此部分重叠也算作匹配)。它还应该替换下面的条件语句,因为它还可以找到下面当前描述的所有情况。

总结一下:希望 awk 在以下情况下打印匹配项:file1 中的 $1 与文件 2 中的 $3 匹配并且:file1 中的 $2-$3 范围与 file2 中的 $5-$6 范围完全相交

如果我的问题不清楚,请告诉我。非常感谢任何帮助,谢谢!(解决方案不必在 awk 中)

鲁巴尔

FILES=/files/*txt   
for f in $FILES ;
do

    awk '
        BEGIN {
            FS = "\t";
        }
        FILENAME == ARGV[1] {
            pair[ $1, $2, $3 ] = 1;
            next;
        }
        {
            if ( pair[ $3, $5, $6 ] == 1 ) {
                print $13;
            }
        }
    ' $(basename $f) /files/refGene.txt > /files/results/$(basename $f) ;
done
4

1 回答 1

0

您只需要使用 2 个数组:

awk -F '\t' '
  NR == FNR {min[$1] = $2; max[$1] = $3; next}
  ($3 in min) && (min[$3] >= $5) && (max[$3] <= $6) {print $13}
'

NR==FNR只是另一种编写方式FILENAME == ARGV[1]——它查看行号而不是文件名。

于 2012-10-04T16:47:44.170 回答