ajout de tailor.py: affichage d'un fichier en mettant en surbrillance certains patterns
This commit is contained in:
		
							parent
							
								
									8e5ad225f1
								
							
						
					
					
						commit
						4593ad8f8e
					
				
							
								
								
									
										119
									
								
								tailor.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										119
									
								
								tailor.py
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,119 @@ | ||||
| #!/usr/bin/env python | ||||
| # -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 | ||||
| 
 | ||||
| u"""Afficher des lignes en mettant en surbrillance certains patterns""" | ||||
| 
 | ||||
| import sys, subprocess, re | ||||
| from collections import OrderedDict | ||||
| 
 | ||||
| def bluef(line, *ignored): return '\x1B[34m%s\x1B[0m' % line | ||||
| def greenf(line, *ignored): return '\x1B[32m%s\x1B[0m' % line | ||||
| def yellowf(line, *ignored): return '\x1B[33m%s\x1B[0m' % line | ||||
| def redf(line, *ignored): return '\x1B[31m%s\x1B[0m' % line | ||||
| def nonef(line, *ignored): return re.sub('\x1B\[.*?m', '', line) | ||||
| 
 | ||||
| DEFAULT_PATTERNS = OrderedDict([ | ||||
|     (r'(?i)error', redf), | ||||
|     (r'(?i)warn(ing)?', yellowf), | ||||
|     (r'(?i)info', bluef), | ||||
|     (None, nonef), | ||||
| ]) | ||||
| FORMATS = OrderedDict([ | ||||
|     ('blue', bluef), | ||||
|     ('green', greenf), | ||||
|     ('yellow', yellowf), | ||||
|     ('red', redf), | ||||
|     ('none', nonef), | ||||
| ]) | ||||
| FORMAT_ALIASES = { | ||||
|     'b': 'blue', | ||||
|     'g': 'green', | ||||
|     'y': 'yellow', | ||||
|     'r': 'red', | ||||
|     '': 'none', | ||||
| } | ||||
| 
 | ||||
| def strip_nl(s): | ||||
|     if s is None: return None | ||||
|     elif s.endswith("\r\n"): s = s[:-2] | ||||
|     elif s.endswith("\n"): s = s[:-1] | ||||
|     elif s.endswith("\r"): s = s[:-1] | ||||
|     return s | ||||
| 
 | ||||
| def run_tailor(inputfile=None, patterns=None): | ||||
|     if inputfile is None: | ||||
|         def next_line(): | ||||
|             while True: | ||||
|                 try: line = sys.stdin.readline() | ||||
|                 except: break | ||||
|                 if line == '': break | ||||
|                 yield line | ||||
|     else: | ||||
|         def next_line(): | ||||
|             p = subprocess.Popen( | ||||
|                 ['tail', '-f', inputfile], | ||||
|                 stdout=subprocess.PIPE, stderr=subprocess.STDOUT) | ||||
|             while True: | ||||
|                 try: line = p.stdout.readline() | ||||
|                 except: break | ||||
|                 if line == '': break | ||||
|                 yield line | ||||
|     if patterns is None: patterns = DEFAULT_PATTERNS | ||||
| 
 | ||||
|     for line in next_line(): | ||||
|         line = nonef(strip_nl(line)) | ||||
|         func = False | ||||
|         mo = None | ||||
|         for p, f in patterns.items(): | ||||
|             if p is None: | ||||
|                 func = f | ||||
|                 mo = None | ||||
|                 break | ||||
|             mo = re.search(p, line) | ||||
|             if mo is not None: | ||||
|                 func = f | ||||
|                 break | ||||
|         if func is not False: | ||||
|             line = func(line, mo) | ||||
|             sys.stdout.write(line) | ||||
|             sys.stdout.write('\n') | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     from argparse import ArgumentParser, RawTextHelpFormatter | ||||
|     AP = ArgumentParser( | ||||
|         formatter_class=RawTextHelpFormatter, | ||||
|         usage=u"%(prog)s [-f INPUTFILE]", | ||||
|         description=__doc__, | ||||
|     ) | ||||
|     AP.set_defaults(inputfile=None, patterns=None, defaults=True) | ||||
|     AP.add_argument('-f', '--follow', dest='inputfile', | ||||
|                     help=u"Spécifier un fichier dont il faut suivre le contenu") | ||||
|     AP.add_argument('-e', '--pattern', action='append', dest='patterns', metavar='PATTERN:FORMAT', | ||||
|                     help=u"""\ | ||||
| Ajouter une spécification de pattern et le format dans lequel il doit être affiché | ||||
| Les formats valides sont: %s | ||||
| Le format par défaut est red""" % ', '.join(FORMATS.keys())) | ||||
|     AP.add_argument('-z', '--no-defaults', action='store_const', dest='defaults', const=False, | ||||
|                     help=u"Ne pas ajouter les patterns par défaut") | ||||
|     o = AP.parse_args() | ||||
| 
 | ||||
|     if o.patterns is None: | ||||
|         patterns = DEFAULT_PATTERNS | ||||
|     else: | ||||
|         patterns = OrderedDict() | ||||
|         for pf in o.patterns: | ||||
|             mo = re.match('(.*):([a-zA-Z]*)$', pf) | ||||
|             if mo is not None: | ||||
|                 p = mo.group(1) | ||||
|                 of = mo.group(2) | ||||
|             else: | ||||
|                 p = pf | ||||
|                 of = 'red' | ||||
|             f = of.lower() | ||||
|             f = FORMAT_ALIASES.get(f, f) | ||||
|             if f not in FORMATS: | ||||
|                 raise ValueError("%s: format invalide" % of) | ||||
|             patterns[p] = FORMATS[f] | ||||
|         if o.defaults: patterns.update(DEFAULT_PATTERNS) | ||||
| 
 | ||||
|     run_tailor(o.inputfile, patterns) | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user