1

目前,我正在努力解决我尚未解决的 AWK 问题。我有一个包含基因组数据的巨大文件(30GB),其中包含一个位置列表(在第 1 列和第 2 列中声明)和第二个包含多个范围的列表(在第 3、4 和 5 列中声明)。我想提取第一个文件中位置落在秒文件中声明的范围内的所有行。由于该位置仅在某个染色体(chr)内是唯一的,因此必须首先测试 chr 是否相同(即文件 1 中的 col1 与文件 2 中的 col3 匹配)

文件 1

chromosome position another....hundred.....columns
chr1       816 .....
chr1       991 .....
chr2       816 .....
chr2       880 .....
chr2       18768 .....
...
chr22      9736286 .....

文件 2

name    identifier chromosome   start    end
GENE1   ucsc.86    chr1         800      900
GENE2   ucsc.45    chr2         700      1700
GENE3   ucsc.46    chr2         18000    19000

预期产出

chromosome position another....hundred.....columns
chr1       816 .....
chr2       816 .....
chr2       880 .....
chr2       18768 .....

我打算做的事情的总结(半编码):

(if $1(in file 1) matches $3(in file 2){            ##test if in the correct chr
   if ($2(in file 1) >= $4 && =< $5 (in file 2){    ##test if pos is in the range
         print $0 (in file 1)                       ##if so print the row from file1
   }
}

如果理解如何通过将 file1 放入一个数组并使用 position 作为索引来解决这个问题,我很高兴,但是我仍然对 chr 有问题,而且除了 file1 放入一个数组中的方式很大(尽管我有 128GB内存)。我用多维数组尝试了一些东西,但也无法真正弄清楚如何做到这一点。

非常感谢您的帮助。

2014 年 8 月 5 日更新在文件 2 中添加了第三行,其中包含相同色度中的另一个范围。就像第二行一样。在下面的脚本中跳过了这一行。

4

2 回答 2

6

它会是这样的,未经测试:

awk '
NR==FNR{ start[$3] = $4; end[$3] = $5; next }
(FNR==1) || ( ($1 in start) && ($2 >= start[$1]) && ($2 <= end[$1]) )
' file2 file1
于 2014-05-07T19:06:00.817 回答
3

数据集的变化实际上极大地修改了这个问题。您引入了一个用作键的元素,并且由于键必须是唯一的,因此它被覆盖了。

对于您的数据集,您最好制作复合键。就像是:

awk '
NR==FNR{ range[$3,$4,$5]; next }
FNR==1
{
    for(x in range) {
        split(x, check, SUBSEP); 
        if($1==check[1] && $2>=check[2] && $2<=check[3]) print $0
    }
}    
' file2 file1
chromosome position another....hundred.....columns
chr1       816 .....
chr2       816 .....
chr2       880 .....
chr2       18768
于 2014-05-08T13:37:55.827 回答