Here is a fairly simple (and hopefully readable) native Python solution. It assumes that the bed file is sorted prior to parsing:
from itertools import groupby
class BedRecord(object):
def __init__(self, chr, start, end, feature):
self.chr = chr
self.start = start
self.end = end
self.feature = feature
def parse_records(in_file):
with open(in_file) as f:
for line in f:
yield BedRecord(*line.strip().split())
def merge_groups(group):
prevoutput = next[next(group)
output = [prev]]
for record in group:
if record.start <= prevoutput[-1].end:
output[-1].end = max(output[-1].end, record.end)
else:
output.append(record)
return output
def main(in_file):
for _, group in groupby(parse_records(in_file), lambda x: (x.chr, x.feature)):
for r in merge_groups(group):
print('\t'.join([r.chr, r.start, r.end, r.feature]))
if __name__ == '__main__':
main('test.bed')