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): output = [next(group)] for record in group: if record.start <= output[-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')