Fast filtering of intervals not falling within a certain distance from known genes
Here's a way to use BEDOPS, which was designed to work fast by using sorted input. Other tools now use sorting to accomplish similar performance benefits.


Convert GTF annotations to a sorted BED file of genes:

$ awk '($3=="gene")' annotations.gtf | gtf2bed - &gt; genes.bed

Sort your intervals, if unsorted:

$ sort-bed intervals.unsorted.bed &gt; intervals.bed

Filter intervals against 1kb-padded genes:

$ bedops --merge genes.bed | bedops --range 1000 --everything - | bedops --not-element-of 1 intervals.bed - &gt; intervals.filtered.bed



We first --merge genes to simplify dealing with overlapping genes and further speed downstream filtering.

The file intervals.filtered.bed will contain intervals from intervals.bed which lie outside of a 1kb-window around merged gene space. 



To run all of this as a one-liner (assuming use of the bash shell):

$ bedops --merge &lt;(awk '($3=="gene")' annotations.gtf | gtf2bed -) | bedops --range 1000 --everything - | bedops --not-element-of 1 &lt;(sort-bed intervals.unsorted.bed) - &gt; intervals.filtered.bed


This creates the same output result, but avoids creation of intermediate files and so should run even faster.



Note: BEDOPS is agnostic about chromosome sizes — this toolkit works with any genome assembly. However, using --range takes care of ranges that would have a negative start position, setting their start coordinates to 0. Bounds aren't really relevant here, in any case, because the bedops --not-element-of step queries input intervals, which should already be within chromosome bounds, unless they were generated incorrectly.