Script di shell per trovare bigrams
Domanda
Sto realizzando uno script di shell per trovare bigrams, che funziona in un certo senso.
#tokenise words
tr -sc 'a-zA-z0-9.' '\012' < $1 > out1
#create 2nd list offset by 1 word
tail -n+2 out1 > out2
#paste list together
paste out1 out2
#clean up
rm out1 out2
L'unico problema è che accoppia le parole dalla fine e dall'inizio della frase precedente.
ad es. per le due frasi "ciao mondo". e "foo bar". farò una battuta con 'mondo. foo'. Sarebbe possibile filtrarli con grep o qualcosa del genere?
So di poter trovare tutti i bigram che contengono un punto fermo con grep [.] ma che trova anche i bigram legittimi.
Soluzione
Sostituisci semplicemente la linea di incollaggio con questa:
paste out1 out2 | grep -v '\..'
Questo filtrerà tutte le righe che contengono un punto che non è l'ultimo carattere di una riga.
Altri suggerimenti
Gli script della shell possono usare pipe.
cat "$@" |
tr -cs "a-zA-Z0-9." '\012' |
{
old="aaa."
while read new
do
case "$old" in
*.) : OK;;
*) echo "$old $new";;
esac
old="$new"
done
}
Il codice utilizza cat
come raccoglitore universale di dati - tr
è un filtro puro che non accetta alcun argomento sul nome file. L'idea di base è che la variabile old contiene la prima parola e new legge la nuova parola. Quando il vecchio termina con un punto (come all'inizio), non costituisce un bigram valido secondo le tue regole. Se vuoi rimuovere i punti dai bigram che terminano la frase, puoi usare:
echo "$old ${new%.}"
La versione senza ornamenti (con punti echo) funziona con shell Bourne e derivati; la versione con $ {new%.}
funziona solo con shell Korn e derivati ??- non con la shell Bourne originale.
Se è necessario utilizzare file temporanei, fare in modo che i loro nomi contengano l'ID processo ($$) e utilizzare trap per rimuoverli:
tmp=${TMPDIR:-/tmp}/bigram.$
trap 'rm -f $tmp.?; exit 1' 0 1 2 3 13 15
...code using $tmp.1, $tmp.2, etc...
rm -f $tmp.?
trap 0
Il segnale 1 è riaggancio (HUP), 2 è interrotto (INT), 3 è chiuso (QUIT), 13 è pipe (PIPE) e 15 è terminato (TERM); 0 è "qualsiasi uscita" ed è quasi juju in questo contesto. Prima di uscire effettivamente, ricordati di annullare la trappola di uscita, come mostrato.
Puoi anche consultare Unix for Poets di Ken Church " (PDF) - un classico che descrive soluzioni a problemi simili.