Tanto tempo fa, nell’altro millennio, quando non esistevano ancora i telefoni cellulari, mi ero fatto uno script molto semplice che attraverso grep trovava il numero di telefono della persona che cercavo.
Nella sua forma più elementare dato il file di testo elenco
composto da righe nome numero basta il comando grep -ih nome elenco
. L’opzione i dice di ignorare le differenze tra maiuscole e minuscole, come si usa nel mondo DOS/Windoze, la h dice di non stampare il nome del file. Funziona ma si può abbellire, cosa che è stata fatta N+1 volte.
Poi il prof (*) Lipari raccontando dei suoi trascorsi mi ha fatto conoscere Bjoern B. Brandenburg. Che è un geek davvero eccezionale. E nelle sue pagine sul sito di UNC c’è un sacco di roba.
E anche se le sue pagine non sono molto aggiornate (ma dice che quando avrà tempo lo farà) ho trovato, tra l’altro una Simple Grep Shell che, grazie anche a Python, fa scintille; io l’ho adottata, così com’è, ma poi l’ho anche usata per far compiere un balzo gigantesco al mio script.
E questa è la mia versione:
#!/usr/bin/env python # -*- coding: utf-8 -*- # da Bjoern B. Brandenburg import sys import os import readline from termcolor import colored HISTFILE = 'qsh_history' EGREP = 'grep' STD_ARGS = ['-ihP', '--color'] class HistFile(object): def __init__(self, file): self.histfile = os.path.join( os.path.abspath(os.path.dirname(sys.argv[0])), file) try: readline.read_history_file(self.histfile) except IOError: pass def store(self): try: readline.write_history_file(self.histfile) except IOError: pass def grep(pattern): args = [EGREP] args.append(pattern) args.extend(STD_ARGS) args.append('ele-tel') # qui i files dei dati args.append('int-tel') args.append('/dev/null') return os.spawnvp(os.P_WAIT, EGREP, args) # sarebbe meglio usare subprocess, prossimamente block_ch = lambda col: colored(u'\u2588', col) def main(args): history = HistFile(HISTFILE) try: while True: print block_ch('cyan') * 20 pattern = raw_input('-> ') if pattern != '': try: pattern = '.*'.join(pattern.split()) grep(pattern) except KeyboardInterrupt: pass except (EOFError, KeyboardInterrupt): print 'Bye.' history.store() if __name__ == '__main__': main(sys.argv)
Allora dati i files “del database” ele-tel
Piero ufficio 3456
Piero lab 7773
Piero officina 1022
Piero de Rossi 3223
Piero Derossi 3009
Piero de' Rossi 3223
Gianpiero 1222
Giorgio Rossi 1992
Piergiorgio Rossi 1990
Françoise 5555
Francoise 5556
Francesca 5557
Renée 5600
Rene' 5700
Müller, Hans 4200
Adams, Douglas N. 4242
e int-tel
lab centralino 7001
portone accesso 1001
sicurezza 1099
beppe 9911
otteniamo:
dove si vede che funziona benissimo, non è necessario ricorrere alle espressioni regolari, funziona con le lettere accentate e esotiche. Dipende com’è fatto il file dei dati: nella versione indicata va bene per lo stile dei Carabinieri — cognome nome 😉
L’unica cosa mia è la sostituzione degli spazi con la regex ‘.*‘ per cui si possono saltare i caratteri esotici (ü e ç negli esempi) mettendo uno spazio.
Il ctrl-D per uscire credo sia abbastanza standard per la/lo shell.
Lo script usa il modulo termcolor (riga 8, ne ho parlato qui) per visualizzare una linea di separazione tra una ricerca e l’altra. Se si vuole si può ometterla togliendo la riga # 46: print block_ch('cyan') * 20
.
Confessione
Ho detto una piccola bugia nel senso che non lo uso per i numeri di telefono ma per altre informazioni che variano piuttosto rapidamente (giornalmente). Funziona alla grande: che grep sia eficiente non è certo una novità per nessuno.
Gli script per costruire il file dei dati sono piuttosto banali e, allo stato attuale, una schifezza. Prossimamente…
Anche lo script Python illustrato potrebbe essere migliorato: usare il nuovo modulo subprocess e ordinare alfabeticamente i risultati, prossimamente, forse.
(*) prof se preferisci posso indicare alla ‘merikana dr, fammi sapere.
Commenti
Bello questo, quando vedo Bjorn (a dicembre) glielo dico!
Chiamami pure come ti pare, “prof”, “doc”, “ehi tu”, per me va sempre bene!
(sto scrivendo slides come un pazzo, prima o poi ve ne metto qualcuno qui sopra)
It’s hard to come by well-informed people for this subject, however, you seem like you know what you’re talking about!
Thanks