3 votes

Script shell pour trouver des bigrammes

Je suis en train de créer un script shell pour trouver des bigrammes, ce qui fonctionne, en quelque sorte.

#tokeniser les mots
tr -sc 'a-zA-z0-9.' '\012' < $1 > out1
#créer une 2ème liste décalée d'un mot
tail -n+2 out1 > out2
#coller les listes ensemble
paste out1 out2 
#nettoyer
rm out1 out2

Le seul problème est qu'il associe des mots de la fin et du début de la phrase précédente.

Par exemple, pour les deux phrases 'hello world.' et 'foo bar.', je vais obtenir une ligne avec ' world. foo'. Serait-il possible de les filtrer avec grep ou quelque chose d'autre?

Je sais que je peux trouver tous les bigrammes contenant un point avec grep [.] mais cela trouve également les bigrammes légitimes.

2voto

Robert Gamble Points 41984

Remplacez simplement la ligne ci-dessous par ceci:

coller out1 out2 | grep -v '\..'

Cela filtrera toutes les lignes contenant un point qui n'est pas le dernier caractère d'une ligne.

2voto

Jonathan Leffler Points 299946

Les scripts Shell peuvent utiliser des pipes.

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
}

Le code utilise cat comme collecteur universel de données - tr est un filtre pur qui n'accepte aucun argument de nom de fichier. L'idée de base est que la variable old contient le premier mot, et new lit le nouveau mot. Lorsque old se termine par un point (comme c'est le cas au début), il ne constitue pas un bigramme valide selon vos règles. Si vous voulez supprimer les points des bigrammes se terminant par des phrases, vous pouvez utiliser :

 echo "$old ${new%.}"

La version non ornée (avec des points émis) fonctionne avec le shell Bourne ainsi qu'avec ses dérivés ; la version avec le ${new%.} fonctionne uniquement avec le shell Korn et ses dérivés - pas le shell Bourne d'origine.

Si vous devez utiliser des fichiers temporaires, alors faites en sorte que leurs noms contiennent l'identifiant de processus ($$) et utilisez trap pour les supprimer :

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

Le signal 1 est déconnexion (HUP), 2 est interruption (INT), 3 est quitter (QUIT), 13 est pipe (PIPE) et 15 est terminer (TERM) ; 0 est 'toute sortie' et est presque juju dans ce contexte. Avant de réellement quitter, n'oubliez pas d'annuler le trap de sortie, comme le montre l'exemple.

2voto

Yuval F Points 15248

Vous voudrez peut-être également consulter "Unix for Poets" de Ken Church (PDF) - un classique décrivant des solutions à des problèmes similaires.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X