Outils pour le traitement des textes Commandes Unix pour traiter les ressources linguistiques Éric Laporte Université Paris-Est Marne-la- Vallée
Sommaire Objectifs Visualiser un échantillon head, tail, less, iconv, sed Extraire des entrées grep Changer de format sed
Commandes Unix pour traiter les ressources linguistiques Avantages Disponibles sur tout environnement Unix Simples : scripts sans déclaration de structures de données, sinon mieux vaut utiliser perl, python, java... Inconvénients Toutes les versions ne font pas la même chose, donc faire des tests... Parfois incompatibles avec UTF-16 (Unitex) Seule structure de données : la ligne ; donc incompatible avec XML
Objectifs Visualiser un échantillon Extraire des entrées d'un lexique Traitement de certaines entrées Changer de format Corpus étiqueté par TreeTagger --> Unitex Construire l'index d'un ensemble de tables Index pour les linguistes Construire une table de classes
Visualiser un échantillon head -30 lexique.lst extraire les 30 premières lignes tail -30 lexique.lst extraire les 30 dernières lignes less -20 lexique.lst visualiser 20 lignes par 20 Vérifier le codage des caractères, le format des entrées... sur quelques exemples
Transcoder La plupart des commandes Unix fonctionnent bien en UTF-8 iconv -f UTF-16LE -t UTF-8 lex16.lst > lex8.lst Dans quel codage sont les caractères d'un fichier texte ? - Ouvrir le fichier avec Notepad++ et observer dans le menu Encodage quelle ligne est cochée : elle indique le codage utilisé. - Ou bien ouvrir le fichier avec MSWord ou Open Office, cliquer sur des lignes de la liste de codages, et vérifier à chaque fois dans l'aperçu si la visualisation correspondante est correcte.
Transcoder iconv -f UTF-16LE -t UTF-8 lex16.lst > lex8.lst Liste des codages disponibles : iconv -l Codage utilisé par Unitex : UTF16-LE Codages particuliers : script sed sed -f accents.sed corpus8.txt > corpus-latex.txt Commande de substitution sed : s///g
sed s+''\([^']\)+{''}\1+g s+à+\\`{a}+g s+à+\\`{a}+g s+â+\\^{a}+g s+é+\\'{e}+g s+è+\\`{e}+g s+ê+\\^{e}+g s+ë+\\"{e}+g s+î+\\^{\\i}+g s+ï+\\"{\\i}+g s+ô+\\^{o}+g s+ù+\\`{u}+g s+û+\\^{u}+g s+ü+\\"{u}+g s+ç+\\c{c}+g s+oe+{\\oe}+g
sed Séparateur de champs : n'importe quel caractère qui n'apparaît pas dans les champs s+é+\\'{e}+g s/é/\\'{e}/g s:é:\\'{e}:g s!é!\\'{e}!g Si on omet le g à la fin, la substitution est faite au plus une fois par ligne, à la première occurrence
Extraire des entrées Extraire des entrées d'un lexique egrep "+hum" lexique.lst > hum.lst extraire les entrées de noms marqués comme désignant des personnes egrep -c "+hum" lexique.lst compter ces entrées egrep -v "+hum" lexique.lst > non-hum.lst extraire les entrées non marquées comme désignant des personnes
grep, egrep Vérifier le format des entrées egrep -v "^[^,.]*,[^,.]*\.[^,.]*$" lexique.lst Syntaxe interne aux lignes Rechercher des contre-exemples Entrées qui n'ont pas exactement les deux délimiteurs attendus dans l'ordre attendu Expressions rationnelles possibles
fgrep Extraire les entrées de certains mots fgrep voici lex.lst fgrep -f liste-nue.lst lex.lst > sous-lex.lst Aucune expression rationnelle possible
Extraire une intersection Extraire les participes passés pour lesquels il existe aussi une entrée comme adjectif (poli) fgrep :Kms delaf.lst > Kms-0.lst abaissé,abaisser.V+z1:Kms abalourdi,abalourdir.V+z3:Kms abandonné,abandonner.V+z1:Kms abasourdi,abasourdir.V+z2:Kms cut -d, -f 1 Kms-0.lst > Kms.lst abaissé abalourdi abandonné abasourdi egrep "\.A.*:ms" delaf.lst > A.lst fgrep -f Kms.lst A.lst > Kms-inter-A.lst
cut Extraire de chaque ligne un ou plusieurs champs abaissé,abaisser.V+z1:Kms abalourdi,abalourdir.V+z3:Kms abandonné,abandonner.V+z1:Kms abasourdi,abasourdir.V+z2:Kms cut -d, -f 1 Kms-0.lst > Kms.lst abaissé abalourdi abandonné abasourdi Les champs sont numérotés à partir de 1 fgrep :Kms delaf.lst | cut -d, -f 1 > Kms.lst
fgrep Extraire les participes passés pour lesquels il existe aussi une entrée comme adjectif (poli) fgrep :Kms delaf.lst | cut -d, -f 1 > Kms.lst abaissé abalourdi abandonné abasourdi egrep "\.A.*:ms" delaf.lst > A.lst fgrep -f Kms.lst A.lst > Kms-inter-A.lst Ce script extrait abolitionniste car aboli est un participe passé
fgrep fgrep -f Kms.lst A.lst > Kms-inter-A.lst Le script extrait abolitionniste car aboli est un participe passé Kms.lst ablutionné aboli abominé abondé A.lst ablatif,.A+z2:ms aboli,.A+z3:ms abolitionniste,.A+z1:ms:fs abominable,.A+z1:ms:fs Kms-inter-A.lst abîmé,.A+z1:ms aboli,.A+z3:ms abolitionniste,.A+z1:ms:fs abonné,.A+z1:ms
fgrep fgrep -f Kms-1.lst A-0.lst > Kms-inter-A-1.lst Le script n'extrait pas abolitionniste Kms-1.lst {ablutionné, {aboli, {abominé, {abondé, A-0.lst {ablatif,.A+z2:ms} {aboli,.A+z3:ms} {abolitionniste,.A+z1:ms:fs} {abominable,.A+z1:ms:fs} Kms-inter-A-1.lst {abîmé,.A+z1:ms} {aboli,.A+z3:ms} {abonné,.A+z1:ms} {abordé,.A+z3:ms}
sed Extraire les participes passés pour lesquels il existe aussi une entrée comme adjectif (poli) Délimiter les champs sed -e "s/.*/{&}/" A.lst > A-0.lst {aalénien,.A+z3:ms} {abactérien,.A+z3:ms} {abaissable,.A+z2:ms:fs} {abaissant,.A+z2:ms} sed -e "s/.*/{&,/" Kms.lst > Kms-1.lst {abaissé, {abalourdi, {abandonné, {abasourdi, fgrep -f Kms-1.lst A-0.lst > Kms-inter-A-1.lst Ce script n'extrait pas abolitionniste
sed sed -e "s/.*/{&}/" A.lst > A-0.lst {aalénien,.A+z3:ms} {abactérien,.A+z3:ms} {abaissable,.A+z2:ms:fs} {abaissant,.A+z2:ms} Expressions rationnelles dans le premier champ de s/// & dans le deuxième champ : la séquence reconnue par le premier champ s/// si on veut reconnaître un seul motif par ligne
Extraire une différence Extraire les participes passés pour lesquels il n'existe pas d'entrée comme adjectif (fallu) egrep "\.A.*:ms" delaf.lst | cut -d, -f1 | sed -e "s/.*/{&,/" > A.lst fgrep :Kms delaf.lst | sed -e "s/.*/{&}/" > Kms.lst {abaissé,abaisser.V+z1:Kms} {abalourdi,abalourdir.V+z3:Kms} {abandonné,abandonner.V+z1:Kms} {abasourdi,abasourdir.V+z2:Kms} fgrep -v -f A.lst Kms.lst > K-sauf-A.lst {abalourdi,abalourdir.V+z3:Kms} {abcédé,abcéder.V+z3:Kms} {abdiqué,abdiquer.V+z1:Kms} {abeausi,abeausir.V+z3:Kms}
Changer de format Changer de format par des substitutions sed -f treetagger2unitex.sed treetagger.txt > unitex.txt Passer du format de sortie de TreeTagger au format d'entrée d'Unitex (tagged text) FranceNAMFrance :PUN: laDET:ARTle nouvelleADJnouveau générationNOMgénération {France,France.N+PR} : {la,le.DET} {nouvelle,nouveau.A} {génération,génération.N}
sed treetagger.txt : laDET:ARTle unitex.txt : {la,le.DET} Scripts sed sed -f treetagger2unitex.sed treetagger.txt > unitex.txt # treetagger2unitex.sed s/DET:ART/.DET/ # remplacer DET:ART par.DET avant : laDET:ARTle après : la.DETle
sed Reconnaître des séquences ambiguës treetagger.txt : ?SENT? unitex.txt : ?{S} SENT : code (sentence) ou mot (sentir) ? Utiliser les délimiteurs de champs s/\tSENT\t/{S}\t/ avant : ?SENT? après : ?{S}? Le délimiteur peut être différent pour chaque champ S'il le faut, introduire des délimiteurs de champs
sed Séquences ambiguës treetagger.txt : ?SENT? unitex.txt : ?{S} SENT : code (sentence) ou mot (sentir) ? Rechercher des exemples de la séquence pour voir si le problème se pose réellement egrep "SENT" treetagger.txt > auxiliaire.lst
sed Changer de délimiteurs treetagger.txt : générationNOMgénération unitex.txt : {génération,génération.N} s/\t/,/ avant : génération.Ngénération après : génération.N,génération Dans les substitutions qui viennent ensuite, les tabulations ont déjà été remplacées par des virgules Le fait d'avoir des substitutions successives introduit une confusion entre niveaux : - virgule du texte ? - virgule-délimiteur ?
sed Substitutions successives treetagger.txt : générationNOMgénération unitex.txt : {génération,génération.N} Utiliser des délimiteurs de champs non ambigus s/\t/\t,/ avant : génération.Ngénération après : génération.N,génération Le délimiteur "\t," est moins ambigu que ","
sed Déplacer, intervertir des champs treetagger.txt : laDET:ARTle unitex.txt : {la,le.DET} Utiliser les délimiteurs de champs s/\.\([^.,\t]\+\)\t,\([^.,\t]\+\)$/,\2.\1/ avant : la.DET,le après : la,le.DET Reconnaître les fins de lignes $ fin de ligne
sed Reconnaître les débuts et fins de lignes.* toute la ligne ^ début de ligne $ fin de ligne
sed Copier un champ treetagger.txt : laDET:ARTle unitex.txt : {la,le.DET} Utiliser les délimiteurs de champs s/.*/{&}/ avant : la,le.DET après : { la,le.DET } Copier & (dans la zone sortie, copie de la zone reconnue)
sed Caractères spéciaux dans le premier champ mais pas dans le deuxième * ^ $ [. s/\.\([^.,\t]\+\)\t,\([^.,\t]\+\)$/,\2.\1/ Séquences spéciales dans le premier champ \+ \? \{ \} \( \)