Find overlapping intervals with bedtools intersect
Use bedtools intersect to report, count, or exclude overlapping intervals between two BED/GFF/VCF files.
Prerequisites
- bedtools installed (`bedtools --version`)
- Two interval files in BED/GFF/VCF format (e.g. features.bed and regions.bed)
1Report A intervals that overlap B
This writes the overlapping portion of every feature in features.bed that hits any interval in regions.bed. Add `-wa` to emit the whole A feature instead of just the overlap, and `-wb` to also append the matching B feature to each line.
bedtools intersect -a features.bed -b regions.bed > overlaps.bedExpected output
chr1 1050 1100 geneA 0 +
chr1 2500 2620 geneC 0 -
chr2 4200 4350 geneG 0 +2Count or exclude overlaps
Swap in `-c` to append a column with the number of B intervals each A feature overlaps, zeros included. To instead keep only the A features with no overlap at all, use `-v`: `bedtools intersect -a features.bed -b regions.bed -v > no_overlap.bed`.
bedtools intersect -a features.bed -b regions.bed -c > counts.bedExpected output
chr1 1000 1200 geneA 0 + 3
chr1 1500 1800 geneB 0 + 0
chr1 2400 2700 geneC 0 - 1
chr2 3300 3600 geneD 0 + 2Troubleshooting
Zero overlaps returned when you expect some
Almost always a chromosome naming mismatch — one file uses "chr1" and the other uses "1". Make the naming consistent across both files (e.g. `sed 's/^chr//' features.bed`) before intersecting.
Intersect is slow or runs out of memory on huge files
Pre-sort both inputs by chromosome then start (`sort -k1,1 -k2,2n in.bed > in.sorted.bed`) and add `-sorted` so bedtools uses the memory-efficient sweep algorithm instead of loading everything at once.