import sys import re import datetime _MARKER = re.compile(r'^------\s*\[{0,1}') # deal with our generated markers _ISO8601 = re.compile(r'^(?P\d{4})-(?P\d{2})-(?P\d{2})T' r'(?P\d{2}):(?P\d{2}):(?P\d{2})') class Record: def __init__(self, message, file, begin): self.message = message self.file = file self.begin = begin def __cmp__(self, other): return cmp(self.timeof(), other.timeof()) def rewind(self): self.file.seek(self.begin) def tostr(self): result = '------ [%s]\n' % self.file.name result += self.message + '\n' return result def timeof(self): message = self.message match = _ISO8601.match(message) if not match: raise ValueError, message L = [] for name in ('year', 'month', 'day', 'hour', 'minute', 'second'): L.append(int(match.group(name))) return datetime.datetime(*L) def main(files): while 1: heads = [] for file in files[:]: # we need to mutate this record = next_record(file) if record is None: files.remove(file) # file done continue heads.append(record) if not heads: break heads.sort() latest = heads.pop(0) sys.stdout.write(latest.tostr()) for record in heads: # rewind files that didn't have the latest record record.rewind() def next_record(f): begin = f.tell() # read (garbage) until past marker line = '' while not _MARKER.match(line): line = f.readline() if not line: break message = '' while 1: line = f.readline() if not line: # we've reached the end of the file break if _MARKER.match(line): # we found the beginning of the next record, rewind and stop f.seek(-len(line), 1) break message += line if message: return Record(message, f, begin) def test(f): # test derived file, making sure that records are saved in ascending order last = datetime.datetime(1969, 1, 1) while 1: record = next_record(f) if record is None: break timeof = record.timeof() if timeof < last: raise ValueError, record.tostr() last = timeof ## if __name__ == '__main__': ## test(open(sys.argv[1], 'r')) if __name__ == '__main__': main([open(x, 'r') for x in sys.argv[1:]])