14.4. Grepmail e Mutt

Grepmail è uno script in perl che permette di fare ricerche molto velocemente nelle vostre mailbox. Ne parlo quì perché esiste uno script di shell ("grepm", in coda a questa sezione), che fa da wrapper ad esso, richiamando direttamente mutt sul risultato. Le sue particolarità sono le seguenti:

Se non trovate il pacchetto già pronto per la vostra distribuzione preferita, scaricate i sorgenti di grepmail dal sito: http://grepmail.sourceforge.net. Per prima cosa, se non li avete già nel vostro sistema, installate i due moduli perl Date::Parse e Date::Manip con i comandi seguenti:

perl -MCPAN -e 'install Date::Parse'
perl -MCPAN -e 'install Date::Manip'
     

quindi compilate come segue (rispondendo eventualmente y alla domanda sull'installazione del modulo Mail::Folder::FastReader, per velocizzare di un 10/20% le ricerche), X.YZ è la versione del programma:

cd /usr/local/src
tar xvzf /percorso/verso/file/coi/sorgenti/grepmail-X.YZ.tar.gz
cd grepmail-X.YZ
perl Makefile.PL
make
make test
make install
     

Se make test segnala qualche errore, usate make testfunc per vedere nello specifico l'errore (a me ne dava uno sulle mailbox tzipped, ma visto che non le uso, non me ne sono preoccupato). Per default la ricerca avviene sia sugli header che nel corpo del messaggio. L'output può essere inviato su un file (otterrete una mailbox standard), o direttamente in pipe di nuovo a grepmail per un ulteriore raffinamento della ricerca. Queste le opzioni per l'uso di grepmail da shell:

grepmail [-abDhilmrRuv] [-s size] [-d "datespec"] [[-e] <expr>] <files...>

-b cerca nel corpo dei messaggi
-d specifica un intervallo di date (*)
-a usa la data di ricezione invece di quella di invio per le ricerche -d
-D modo debug
-e dichiara esplicitamente che la seguente è l'espressione da
   cercare (utile per ricerche su stringhe che iniziano con "-")
-h cerca negli header dei messaggi
-H stampa solo gli header ma non i corpi delle email trovate
-i ignora maiuscole e minuscole nell'espressione
-l visualizza un elenco dei file che contengono l'espressione cercata
-M non cercare negli allegati MIME non testuali
-m appende "X-Mailfolder: <folder>" agli header per indicare in
   quale folder è avvenuto il match con l'espressione cercata
-n visualizza i numeri di riga (e il nome del file se necessario)
   delle email (lo script "grepm" non funzionerà...)
-q modo silenzioso -- non visualizza gli avvertimenti
-r visualizza i nomi dei file e il numero di email che soddisfano
   l'espressione
-R ridiscende un albero di directory ricorsivamente
-s restringe il risultato alle email inferiori ad una certa dimensione
   (in bytes)
-u assicura che non ci siano email diplicate nell'output
-v visualizza le email che NON soddisfano l'espressione
-V visualizza il numero di versione
-Z non usare Mail::Folder::FastReader anche se presente nel sistema

(*) Le date devono essere in uno dei formati seguenti:
  una data come "today", "1st thursday in June 1992" (richiede
  Date::Manip), "05/18/93", "12:30 Dec 12th 1880", "8:00pm
  december tenth", oppure "before", "after", o "since", seguito
  da una data come specificata sopra, oppure "between <date>
  and <date>", dove <date> è definita come sopra.
     

Seguono alcuni esempi, presi dalla manpage:

# conta il numero di email ("." "matcha" tutte le email.)
grepmail -r . sent-mail

# trova tutte le email maggiori a 2000 byte sui "books"
grepmail books -s 2000 sent-mail

# trova tutte le email inviate ieri
grepmail -d yesterday sent-mail

# trova tutte le email contenenti "research" inviate prima del primo
# giovedì di giugno 1998 (richiede il modulo Date::Manip)
grepmail research -d "before 1st thursday in June 1992" sent-mail

# trova tutte le email contenenti "research" inviate prima del
# primo giugno 1998
grepmail research -d "before 6/1/92" sent-mail

# trova tutte le email ricevute dal 8/20/98 che non riguardano
# "research" o "job", ignorando maiuscole e minuscole
grepmail -iv "(research|job)" -d "since 8/20/98" saved-mail

# trova tutte le email su "mime" ma non su "Netscape". Limita la
# ricerca al solo corpo (molte email contengono "mime" negli header)
grepmail -b mime saved-mail | grepmail Netscape -v

# visualizza un elenco delle mailbox contenenti messaggi da "Rodney".
# Limita la ricerca ai soli header, poiché il testo quotato
# delle email potrebbe contenere il pattern
grepmail -hl "^From.*Rodney" saved-mail*

# trova tutte le email con il testo "Pilot" sia negli header
# che nel corpo del messaggio
grepmail -hb "Pilot" saved-mail*

# conta il numero di messaggi su "grepmail" in tutte le mailbox
# "saved-mail"
grepmail -br grepmail saved-mail*

# rimuove qualsiasi duplicato in una mailbox
grepmail -u saved-mail

# converte una mailbox Gnus in formato mbox
grepmail . gnus-mailbox-dir/* > mbox
     

grepm è un wrapper per grepmail che invia l'output direttamente a mutt (si usa esternamente ad esso, direttamente da riga di comando, e lo richiama in automatico sul risultato). Si usa esattamente come il tool originale, con le stesse opzioni (visto che è un wrapper, e quindi passa tutto a grepmail). Segue lo script (gli eventuali aggiornamenti su http://privat.schlund.de/barsnick), copiatelo in qualche directory contenuta nel vostro PATH e rendetelo eseguibile con chmod 755 grepm.

#!/bin/sh

# grepm - a wrapper for grepmail utilizing mutt

# grepm-0.6

# written 1998-11-xx by Moritz Barsnick <barsnick@gmx.net>
# updated 1998-12-22:   added "-m" option for grepmail
#           added "exit 1" to trap
# updated 1999-01-04:   added check for empty "mailbox" (don't open mutt)
#           added messages
#           added umask (to keep others from reading your messages)
# updated 1999-01-19:   added trap for SIGPIPE (any other suggestions?)
# updated 1999-07-05:   added $TMPDIR; we're still subject to races ($TMPFILE
#               might exist)
# updated 1999-11-29:   have mutt open the temporary mailbox read-only -
#               there's no use in editing it anyway


PROGNAME=`basename "$0"`
TMPDIR=${TMPDIR-/tmp}

umask 077

if [ $# -lt 1 ]; then
  echo 1>&2 "Usage: ${PROGNAME} arguments"
  exit 1
fi

TMPFILE="${TMPDIR}/grepmail-output.$$"

# I _would_ check this with "-e", but not all /bin/sh's understand it
# so this is just a kludge

if [ -f ${TMPFILE} -o -d ${TMPFILE} -o -w ${TMPFILE} ]; then
  echo 1>&2 "Temporary file ${TMPFILE} exists for some reason! Aborting."
  exit 1
fi

trap "rm -f ${TMPFILE}; exit 1" 1 2 3 13 15

grepmail -m "$@" > "${TMPFILE}"
if [ `wc -c "${TMPFILE}" | awk '{print $1}'` -gt 0 ]; then
  echo 1>&2 "Calling mutt on results file (${TMPFILE})."
  mutt -R -f "${TMPFILE}"
else
  echo 1>&2 "No matches."
fi

rm -f "${TMPFILE}" && echo 1>&2 "Deleted results file (${TMPFILE})."