Source code for leo.external.stringlist

#@+leo-ver=4-thin
#@+node:ville.20090720135131.1484:@thin stringlist.py

#@<< imports >>
#@+node:ville.20090720135131.1640:<< imports >>
import re
import subprocess
#@nonl
#@-node:ville.20090720135131.1640:<< imports >>
#@nl
#@+others
#@+node:ville.20090720135131.1493:class SList
[docs]class SList(list): """List derivative with a special access attributes. These are normal string lists, but with the special attributes: .l: value as list (the list itself). .n: value as a string, joined on newlines. .s: value as a string, joined on spaces. """ #@ @+others #@+node:ville.20090720135131.1494:get_list
[docs] def get_list(self): return self
#@-node:ville.20090720135131.1494:get_list #@+node:ville.20090720135131.1495:get_spstr
[docs] def get_spstr(self): self.__spstr = ' '.join(self) return self.__spstr
#@-node:ville.20090720135131.1495:get_spstr #@+node:ville.20090720135131.1496:get_nlstr
[docs] def get_nlstr(self): self.__nlstr = '\n'.join(self) return self.__nlstr
#@-node:ville.20090720135131.1496:get_nlstr #@+node:ville.20090720135131.1501:property accessors l = property(get_list) s = property(get_spstr) n = property(get_nlstr) #@nonl #@-node:ville.20090720135131.1501:property accessors #@+node:ville.20090720135131.1498:grep
[docs] def grep(self, pattern, prune = False, field = None): """ Return all strings matching 'pattern' (a regex or callable) This is case-insensitive. If prune is true, return all items NOT matching the pattern. If field is specified, the match must occur in the specified whitespace-separated field. Examples:: a.grep( lambda x: x.startswith('C') ) a.grep('Cha.*log', prune=1) a.grep('chm', field=-1) """ def match_target(s): if field is None: return s parts = s.split() try: tgt = parts[field] return tgt except IndexError: return "" if isinstance(pattern, basestring): pred = lambda x : re.search(pattern, x, re.IGNORECASE) else: pred = pattern if not prune: return SList([el for el in self if pred(match_target(el))]) else: return SList([el for el in self if not pred(match_target(el))])
#@-node:ville.20090720135131.1498:grep #@+node:ville.20090720135131.1499:fields
[docs] def fields(self, *fields): """ Collect whitespace-separated fields from string list Allows quick awk-like usage of string lists. Example data (in var a, created by 'a = !ls -l'):: -rwxrwxrwx 1 ville None 18 Dec 14 2006 ChangeLog drwxrwxrwx+ 6 ville None 0 Oct 24 18:05 IPython a.fields(0) is ['-rwxrwxrwx', 'drwxrwxrwx+'] a.fields(1,0) is ['1 -rwxrwxrwx', '6 drwxrwxrwx+'] (note the joining by space). a.fields(-1) is ['ChangeLog', 'IPython'] IndexErrors are ignored. Without args, fields() just split()'s the strings. """ if len(fields) == 0: return [el.split() for el in self] res = SList() for el in [f.split() for f in self]: lineparts = [] for fd in fields: try: lineparts.append(el[fd]) except IndexError: pass if lineparts: res.append(" ".join(lineparts)) return res
#@-node:ville.20090720135131.1499:fields #@+node:ville.20090720135131.1500:sort
[docs] def sort(self,field= None, nums = False): """ sort by specified fields (see fields()) Example:: a.sort(1, nums = True) Sorts a by second field, in numerical order (so that 21 > 3) """ #decorate, sort, undecorate if field is not None: dsu = [[SList([line]).fields(field), line] for line in self] else: dsu = [[line, line] for line in self] if nums: for i in range(len(dsu)): numstr = "".join([ch for ch in dsu[i][0] if ch.isdigit()]) try: n = int(numstr) except ValueError: n = 0; dsu[i][0] = n dsu.sort() return SList([t[1] for t in dsu])
#@-node:ville.20090720135131.1500:sort #@-others #@-node:ville.20090720135131.1493:class SList #@+node:ville.20090720134348.1860:shcmd
[docs]def shcmd(cmd): """ Execute shell command, capture output to string list """ out = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).communicate()[0] sl = SList(out.split('\n')) return sl
#@-node:ville.20090720134348.1860:shcmd #@-others #@-node:ville.20090720135131.1484:@thin stringlist.py #@-leo