import re class AwkUnhandledLine( RuntimeError ): pass class Awk: """awk-like mapping from patterns to handlers.""" def __init__(self): # Start without any patterns self.pats=[] def add(self,pattern,handler=None): # Add a pattern and its handler, # precompiling the pattern self.pats.append((re.compile(pattern),handler)) def process(self,line): # Find the first pattern that matches the input, # and call the handler with the result of the match. for pat, handler in self.pats: m = pat.match(line) if m: if callable(handler): return handler(**m.groupdict()) else: return handler raise AwkUnhandledLine( line ) class AwkFileInput(Awk): def __init__(self): import fileinput self.fileinput = fileinput Awk.__init__(self) def processinput(self): for line in self.fileinput.input(): try: self.process(line) except AwkUnhandledLine, e: raise AwkUnhandledLine( "Don't understand line %d of file %s: %s" % (fileinput.filelineno(), fileinput.filename(), line) ) # example: def handle_thing(name=None,num=0): if name: print name, "=", float(num) else: print float(num), "has no name" def example(): a = AwkFileInput() a.add("^#") # Ignore comments (handler==None) a.add("^(?P<num>\d+\.\d+)", handle_thing) # Print numbers a.add("^(?P<name>\w+)\s+(?P<num>\d+)", handle_thing) # Print named numbers a.processinput()