Lingunix

Les outils unix appliqués à la recherche linguistique et psycholinguistique

  • Augmenter la taille
  • Taille par défaut
  • Diminuer la taille
Introduction Unix

Introduction : AWK pour les linguistes

Imprimer PDF

Le nom de la commande AWK provient de la première lettre du nom de ses trois créateurs : Alfred Aho, Peter Weinberger et Brian Kernighan. AWK est presque un langage à lui seul, c'est un outil puissant permettant de faire des opérations bien plus complexes que GREP et SED ne peuvent le faire. On peut faire des opérations d'arithmétique, de logique, de filtrage, de substitution, d'édition de tableaux... D'ailleurs, nous utiliserons principalement AWK comme un éditeur de tableau. (sachant que la base de donnée Lexique3.txt est un tableau).

Le principe de fonctionnement de la commande AWK est le même que pour GREP et SED, dans le sens ou ces commandes peuvent soit recevoir et traiter un flux de données issu d'une commande préalablement effectuée (cat fichier.txt | awk), ou soit éditer directement un fichier (awk fichier.txt).

I/ Éditer un tableau avec AWK


On peut facilement lire, écrire ou modifier un tableau avec AWK. Une colonne d'un tableau est représentée par le caractère dollar ($) suivi de son numéro de référence. Par exemple, la première colonne sera accessible par $1, la deuxième par $2, la troisième par $3, etc...
Il faudra aussi préciser le caractère de séparation de champs présent entre chaque colonne avec -F. Le caractère de séparation de champs  pourra aussi être précisé par FS lorsqu'on le fait dans une instruction. Il en est de même pour le caractère de séparation de ligne, habituellement \n, qui sera défini par RS,  mais nous verrons ça plus tard.

Exemple :

awk -F"\t" '{print $1,$4}' Lexique3.txt

Dans le fichier Lexique3.txt (téléchargeable sur lexique.org), le caractère de séparation employé est tabulation (\t). L'action {print $1,$4} va envoyer à la sortie de la commande AWK la première et la quatrième colonne ($1,$4) qui correspondent respectivement au mot et à sa catégorie grammaticale.

Il est cependant nécessaire de redéfinir le caractère de séparation qui à la sortie de l'éditeur awk est par défaut un espace. Nous devrons donc ajouter par exemple après l'action print une tabulation entre chaque colonne à l'aide de \t :

awk -F"\t" '{print $1,"\t"$4}' Lexique3.txt

Nous retiendrons de ces deux exemples la manipulation des colonnes d'un tableau avec le caractère dollar suivi de son numéro ($1,$2,$3,etc...) et, le renseignement des caractères de séparation de champs pour la lecture d'un tableau (-F"\t") et avec l'ajout du caractère à la sortie de la commande awk (print $1,"\t"$4).

Notes :

Pour des raisons de confort de lecture des résultat, vous pouvez rediriger le résultat de chacune des commandes présentées ici dans l'éditeur LESS via un pipe (|) :

awk -F"\t" '{print $1"\t",$4}' Lexique3.txt | less

Pour arrêter le défilement d'un flux ou pour sortir de l'éditeur LESS, faites : CTRL Z

II/ Les Motifs avec AWK


Les motifs acceptés par AWK peuvent être une expression régulière, une relation, un test de logique ou une combinaison de plusieurs expressions régulières.

AWK comme un filtre GREP avec une expression régulière

commande :

awk '/voiture/ {print}' Lexique3.txt

Cette commande va envoyer sur la sortie standard toutes les lignes dans lesquelles se trouve l'expression régulière « voiture ». Pour avoir un résultat un peu plus confortable, on peut demander à ce que la commande awk ne retourne à sa sortie que la première colonne de la base Lexique3.txt :

awk -F"\t" '/voiture/ {print $1}' Lexique3.txt

résultat :

voituraient
voiturait
voiture
voiture
voiture-balai
voiture-bar
voiture-lit
voiture-restaurant
voiturer
voitureront
voitures
voitures
voitures-balais
voiturette
voiturettes
voitur

Remarques :

Regardez attentivement la liste du résultat et comparez-la à l'expression régulière demandée ci-dessus.
Nous demandions à l'aide d'une expression régulière la chaîne de caractères « voiture » et nous avons eu dans notre résultat la chaîne de caractères « voituraient » qui ne correspond pas à l'expression exacte « voiture ». Pour comprendre pourquoi nous avons eu ce résultat si surprenant, il est nécessaire de connaître un peu l'organisation de la base Lexique3 et le fonctionnement de tous filtres Unix qui se respectent :

  • Premièrement, dans la base Lexique3 se trouve une colonne intitulée lemme (la colonne numéro 3 accessible via awk '{print $3}').

 

  • Deuxièmement, les filtres Unix, qu'il s'agisse de GREP ou de AWK, traitent un fichier ligne par ligne sur toute la ligne. Autrement dit, les filtres Unix cherchent l'expression régulière sur toute la ligne d'un fichier. Cela à pour conséquence que si l'expression régulière demandée est présente quelque part sur la ligne, comme par exemple dans la colonne lemme, la ligne complète sera filtrée et envoyée à la sortie. Voyons ce qui se passe si nous demandons à AWK de nous donner à sa sortie la colonne 3 correspondant au lemme de l'expression régulière recherchée :


awk -F"\t" '/voiture/ {print $1"\t",$3}' Lexique3.txt

voituraient        voiturer
voiturait        voiturer
voiture             voiture
voiture             voiturer
voiture-balai        voiture-balai
voiture-bar        voiture-bar
voiture-lit        voiture-lit
voiture-restaurant    voiture-restaurant
voiturer        voiturer
voitureront        voiturer
voitures        voiture
voitures        voiturer
voitures-balais         voiture-balai
voiturette        voiturette
voiturettes        voiturette
voituré             voiturer


On pourra dire ce que l'on veut du lemme « voiturer », en attendant il explique la présence de l'expression « voituraient » dont le lemme est « voiturer » qui contient la sous chaîne de caractères « voiture » dans notre résultat. (voyez ci-après comment pallier ce problème)

Les tests de relations de champs avec AWK


Notre problème précédant me permet d'introduire facilement les tests de relations avec AWK, dont le but est de vérifier si un champs particulier (une colonne) contient une expression régulière. Nous allons, avec les tests de relations, pouvoir par exemple travailler uniquement dans la première colonne. Cela signifie que si nous cherchons l'expression régulière « voiture » seulement dans la première colonne, nous n'aurons que les mots contenant la chaîne « voiture » et rien d'autre :

awk -F"\t" '$1~/voiture/ {print $1}' Lexique3.txt

Résultat :

voiture
voiture
voiture-balai
voiture-bar
voiture-lit
voiture-restaurant
voiturer
voitureront
voitures
voitures
voitures-balais
voiturette
voiturettes

Explications :

La commande ci-dessus considère que le caractère de séparation est une tabulation (-F"\t"), puis elle sélectionne la colonne 1 ($1~), ensuite elle cherche l'expression « voiture » dans la colonne sélectionnée (/voiture/) et enfin elle affiche la première colonnes des lignes sélectionnées (print $1).
Dans notre exemple, si nous souhaitions rechercher l'expression exacte « voiture » sans retenir celles qui la contiennent, nous devrions alors la préfixer du caractère symbolisant le début de ligne (^) et la suffixer avec le caractère symbolisant la fin de ligne ($) (on utilise le caractère de fin de ligne ($) car nous avons préalablement sélectionné la colonne ($1~) s'affichant désormais sur une ligne) :

awk -F"\t" '$1~/^voiture$/ {print $1}' Lexique3.txt

résultat :

voiture
voiture

Les combinaisons logiques et les opérateurs booléens

Le ET logique : &&

Le ET logique avec AWK symbolisé par un double esperluette (&&) est très utile car il permet de vérifier par exemple deux relations de champs.
Vous avez très probablement remarqué que dans la langue française, il existe un certain nombre de mots partageant le même orthographe alors qu'ils appartiennent à différentes catégories grammaticales. Je sais que vous savez qu'il s'agit des homographes, mais je préfère m'adresser à vous comme un programmeur. Au passage, je peux vous dire que l'application systématique d'une définition linguistique n'est pas toujours si évidente que ça !
Pour en revenir au homographes, par exemple le mot « plus » écrit de cette manière peut être soit un adverbe ou soit le participe passé du verbe « plaire ».

Le ET logique nous donne la possibilité de choisir l'expression régulière ayant l'orthographe « plus » ET appartenant à la catégorie grammaticale souhaitée (adverbe ou verbe) :

awk '$1~/plus/ && $4~/ADV/ {print $1,$3,$4}' Lexique3.txt

résultat :

plus plus ADV

awk '$1~/plus/ && $4~/VER/ {print $1,$3,$4}' Lexique3.txt

résultat :

plus plaire VER
plus plus VER
plusse plaire VER

Dans cet exemple, nous avons travaillé sur la première colonne de Lexique3.txt correspondant à l'orthographe du mot ET sur la quatrième colonne correspondant à sa catégorie grammaticale. Je me suis permis d'afficher (avec print) entre la colonne $1 et $4, la colonne $3 (correspondant au lemme du mot) afin de rendre le résultat un peu plus compréhensible.

Le OU logique : ||

Symbolisé par deux pipes (||) le OU logique est généralement un peu moins pertinent que le ET logique :

awk '$4~/ADJ/ || $4~/ADV/ {print $1,$3,$4}' Lexique3.txt | less

Cette commande retournera tous les adjectifs ainsi que tous les adverbes de la base de donnée Lexique3.txt.

Le NON : !

Symbolisé par un point d'exclamation, le NON appelé aussi « contraire de » ou « différent de » est bien plus subtile qu'il n'y paraît. En effet cet opérateur nous permettrait par exemple de récupérer tous les mots sauf ceux qui contiennent la lettre e (comme la si bien fait Georges Perec) :

awk '!($1~/e/) {print $1,$3,$4}' Lexique3.txt | less

Attention, pensez à utiliser des parenthèses avec le NON, et remarquez aussi que la commande ci-dessus ne tient pas compte ni des E majuscules ni des E accentués, c'était juste pour l'exemple.

Pour finir, vous pouvez aisément assembler des combinaisons d'opérateurs logiques et définir des priorités d'exécutions à l'aide des parenthèses :

awk '!($1~/e/) && !($1~/a/) {print $1}' Lexique3.txt | less

awk '($4~/ADJ/ || $4~/ADV/) && $1~/plus/ {print $1,$3,$4}' Lexique3.txt | less

III/ Les Actions avec AWK


Nous avons vu précédemment l'usage des motifs avec la commande AWK. Voyons maintenant ce que nous pouvons faire de ces motifs en nous servant d'actions. Il existe de nombreuses actions et depuis le début de cette introduction et j'en ai utilisé une que vous reconnaitrez :

Fonctions traitants de chaînes de caractères :


Les fonctions traitant de chaînes de caractères sont absolument vitales pour le fonctionnement d'un script AWK d'autant plus s'il est orienté dans une manipulation à des fins linguistiques.

L'action print :

L'action print est employée pour afficher le résultat d'une commande AWK sur la sortie standard à savoir l'écran de votre terminal.

awk -F\t '{print $1,$2,$3}' Lexique3.txt

Cette commande va afficher la première, la deuxième et la troisième colonne de toutes les lignes du fichier Lexique3.txt.

L'action printf :

L'action printf est une autre manière d'afficher le résultat d'une commande qui sera en général peu utile pour nous... Je préfère aborder l'utilité de cette action plus tard.

L'action length :

Cette action calcule le nombre de caractères constituant une chaîne, une ligne ou une colonne :

awk -F"\t" '{print $1,length($1)}' Lexique3.txt | less

Ce script calcule le nombre de caractères constituant chaque mot présent dans la première colonne du fichier Lexique3.txt. Puis, il écrit le mot suivit du nombre de caractères le constituant.

Résultat :

a l'instar 10
a posteriori 12
abaca 5
abaissa 7

L'action gsub :

Cette action nous donne l'occasion de substituer une chaîne de caractère par une autre exactement comme le fait l'éditeur SED :

echo "bonjour" | awk '{gsub("bonjour","hello"); print}'

La commande ci-dessus remplace la chaîne de caractères « bonjour » (initié par echo) par « hello ».

L'action  index :

L'action index retourne la position la plus à gauche d'une sous chaîne dans une chaîne de caractères. Dans l'exemple qui suit, nous recherchons la valeur numérique de la position la plus à gauche de la lettre « l » dans le mot « ville » :

echo "ville" | awk '{print index($1,"l")}'

résultat :

3

Remarques :

Dans cet exemple, « $1 » représente la première colonne du résultat de la commande echo (qui se fait toujours sur une colonne, mais il fallait tout de même le préciser).
Rappelons-nous que lorsque nous cherchons un mot dans un index (un dictionnaire), nous commençons par lire la première lettre la plus à gauche, puis la deuxième, puis la troisième, etc...

L'action substr :

L'action substr retourne à partir de n caractères en partant de la gauche une sous chaîne de m caractères : substr (chaîne,n,m) :

echo "refroidissement" | awk '{print substr($1,3,5)}'

Résultat :

froid

Fonctions traitants de nombres :


Voici la liste des fonctions mathématiques disponible avec AWK :

cos (cosinus), sin (sinus), exp (exponentiel), log (logarithme), sqrt (racine carré), rand (randomisation 0 1), srand (ré-initialisation de rand), int (valeur entière).

Exemple :

echo "25" | awk '{print cos($1)}'

résultat :

0,991203

Retour sur les motifs : BEGIN et END :


Ces deux sélections particulières ou « patterns » donnent la possibilité d'exécuter des instructions AVANT et APRÈS un programme AWK. Le sélecteur BEGIN est plus souvent employé pour signaler un traitement à venir ou pour initialiser les variables  d'un programme :

awk 'BEGIN {print "calcul de la racine carré de 25 :"} {print sqrt(25)}'
awk 'BEGIN {X=25} {print "calcul de la racine carré de " X} {print sqrt(X)}'


IV/ Les variables :


Les commandes AWK étant interprétées - et comme le plus souvent dans ce cas de figure - il n'est pas nécessaire de déclarer les variables avant de les initialiser. On peut directement initialiser la variable. D'autre part l'appel d'une variable dans une commande AWK se fait sans le caractère $ (contrairement au Shell). Si on souhaite initialiser une variable avec une valeur non nul, on utilisera l'instruction BEGIN.

awk 'BEGIN {var="retourner"} {print "nombre de lettres dans" var} {print length(var)}'

Variables prédéfinies :


Variable Description
ARGC Nombre d'arguments de la ligne de commande
ARGIND Index du tableau ARGV du fichier courant
ARGV Tableau des arguments de la ligne de commande
CONVFMT Format de conversion pour les nombres
ENVIRON Tableau contenant les valeurs de l'environnement courant
ERRNO Contient une chaine décrivant une erreur
FIELIWIDTHS Variable expérimentale à éviter d'utiliser
FILENAME Nom du fichier d'entrée
FNR Numéro d'enregistrement dans le fichier courant
FS Contrôle le séparateur des champs d'entrée
IGNORECASE Contrôle les expressions régulières et les opérations sur les chaînes de caractères
NF Nombre de champs dans l'enregistrement courant
NR Nombre d'enregistrements lus
OFMT Format de sortie des nombres
OFS Séparateur des champs de sortie
ORS Séparateur des enregistrements de sortie
RLENGTH Longueur de la chaîne sélectionnée par le critère "\ n"
RS Contrôle le séparateur des enregistrements d'entrée "\ n"
RSTART Début de la chaîne sélectionnée par le critère
SUBSEP Séparateur d'indiçage

V/ Conclusion :


Dans cette petite introduction à l'éditeur AWK, je ne vous ai présenté qu'une infime partie de ce que l'on peut faire avec cet outil. J'ai agis de la sorte pour des raisons pédagogiques. Vous devriez cependant êtres capables d'une part de comprendre des scripts écrits en AWK de niveau intermédiaire et d'autre part d'écrire des petits scripts grâce à cette introduction. Je vous conseille de faire appel à plusieurs sources d'informations et de vous entrainer à rédiger des scripts même s'ils n'ont que peut d'intérêts au début. C'est vrai qu'il existe de nombreuses solutions pour exploiter des données, mais avec AWK vous aurez un certain sentiment d'autonomie et de liberté.

Pou finir, vous habituer à la syntaxe d'AWK est une très bonne préparation à la programmation en  langage C.

Bonne programmation !

SCHMITT Vivien http://www.lingunix.orghttp://www.tsgeri.net

Mise à jour le Vendredi, 15 Avril 2011 21:08
 

Introduction à SED : éditeur de flux pour les linguistes

Imprimer PDF

Le nom SED provient de l'abréviation de Stearm Editor pouvant être traduit par « éditeur de texte orienté flux ». L'éditeur sed traite un fichier texte ligne par ligne, que le flux provienne d'un autre filtre (cat texte.txt | sed) ou qu'il soit initié par sed lui même (sed fichier.txt).

Les possibilités de sed

Sed a quatre possibilités de fonctionnement, il peut :

  1. ajouter une ligne après une ligne (a)
  2. ajouter une ligne avant une ligne (i)
  3. afficher certaines lignes comme un filtre (p)
  4. substituer certaines lignes (s).


Nous utiliserons principalement l'éditeur sed comme outil de substitution permettant de remplacer partiellement ou totalement le contenu d'une ligne.

Exemple :

cat fichier_texte.txt | sed s/hello/bonjour/g > fichier_resultat.txt

Cette commande va remplacer toutes les occurrences « hello » par « bonjour » du fichier « fichier_texte.txt puis elle va rediriger le résultat dans le fichier_resultat.txt.

Les options de sed :

L'éditeur sed possède 4 options donnant la possibilité d'affiner le traitement de substitution :

  • g : remplacer tous les motifs dans la ligne
  • i : ne remplacer qu'à partir de la i-eme occurrence du motif dans la ligne
  • p : afficher la ligne si une substitution est réalisée
  • w : envoyer le résultat de la substitution dans un fichier

 

L'éditeur sed en pratique

Le cas de la substitution :

sed 's/chaine_de_caractère/chaîne_de_substitution/g'

Dans ce cas la chaîne de caractère sera remplacée par la chaîne de substitution dans toute la ligne.

Exemple :

Dans l'exemple suivant, nous allons remplacer la chaîne de caractère coriger par corriger :

echo "texte à corigé" | sed 's/corigé/corriger/g'

Résultat :

texte à corriger


Explication :

Nous avons fait appel à la commande echo pour écrire le texte « texte à coriger » dont nous avons rediriger le résultat (sous forme de flux) à l'aide d'un pipe ( le batonnet | ) dans l'éditeur sed (l'éditeur de flux). La commande sed 's/coriger/corriger/g' a remplacé coriger par corriger et nous a renvoyé la réponse dans le terminal.

Voilà, maintenant vous savez comment fonctionne les correcteurs automatiques d'orthographe et vous êtes désormais capable d'en programmer un !!! facile non ? (j'aurais pu aussi vous faire le coup du traducteur d'anglais-français en remplaçant hello par bonjour Cool )

En réalité l'éditeur sed est bien plus utile que cela, il est rarement utilisé comme un correcteur d'orthographe, mais quand on maîtrise cet outil, on peut en faire ce que l'on veut !

Aller plus loin avec sed

Supprimer tous les caractères spéciaux d'un texte :

echo "bonjour à tous !!! comment allez-vous???" | sed 's/\W/ /g'

Résultat :

bonjour à tous  comment allez vous

Explication :

Cette commande est très utile car elle permet de se débarrasser une bonne fois pour toute de tous les caractères spéciaux présent dans un texte. (les caractères non alphanumériques)

Les crochets avec sed :

L'usage des crochets [ ] avec sed donnent la possibilité de remplacer plusieurs caractères par un même caractère :

echo  "je vous ai répété cet après-midi qu'il n'y a pas d'accents en code ASCII, même avec le verbe être" | sed 's/[éèê]/e/g'

Résultat :

je vous ai repete cet apres-midi qu'il n'y a pas d'accents en code ASCII, meme avec le verbe etre

Explication

A l'aide des crochets [ ] nous avons remplacé les caractères é, è et ê par e.

Enchaînement de substitution avec sed :

Nous pouvons aisément exécuter successivement des blocs de substitutions séparés par un point-virgule avec l'éditeur sed :

echo  "le chemin des dames fût une boucherie" | sed 's/le/ART/g; s/chemin/NOM/g; s/des/ART-P/g; s/dames/NOM/; s/fût/VERBE/g; s/une/ART-I/; s/boucherie/NOM/g'

Résultat :

ART NOM ART-P NOM VERBE ART-I NOM

Explication :

Nous avons successivement remplacé les mots par leur nature : "le" par "ART"; "chemin" par "NOM"; des  par "ART-P"; etc...
Vous remarquerez que les simples quotes se trouvent au début et à la fin du script mais pas à la fin de chaque bloc se terminant obligatoirement par un point-virgule afin de permettre l'exécution séquentiel de remplacement.

Remplacer les lettres d'un mots par C ou V :

echo "Dans ce texte, toutes les lettres vont être remplacées par C pour consonne ou V pour Voyelle" | sed 's/[zrtpqsdfghjklmwxcvbnZRTPQSDFGHJKLMWXCVBN]/C/g; s/[aeiouyAEIOUY]/V/g'

Résultat :

CVCC CV CVCCV, CVVCVC CVC CVCCCVC CVCC êCCV CVCCCVCéVC CVC C CVVC CVCCVCCV VV C CVVC CVVVCCV

Explication :

Vous avez sans doute repéré les crochets [ ] entre lesquels se trouvent une fois toutes les consonnes et toutes les voyelles en minuscule puis en majuscule.
Ces crochets servent à définir plusieurs caractères à remplacer par un même caractère, ici C ou V.
Ce script remplace d'abord toutes les consonnes par la lettre C puis toutes les voyelles par la lettre V.

(je vous laisse deviner pourquoi on remplace d'abord les consonnes par C puis les voyelles par V et non l'inverse !)

Il y a deux choses à voir dans ce script :

  • les crochets permettant de définir plusieurs caractères à remplacer.
  • l'enchaînement successif de blocs de remplacements séparés par des point-virgules (voir ci-haut)


Notez aussi que les lettres accentuées n'ont pas été remplacées. Cela fût volontaire de ma part afin de ne pas surcharger le script exemple. Vous retiendrez qu'il est nécessaire de tenir compte de tous les caractères accentués existant - aussi bien pour les voyelles que pour les consonnes. Voir le script complèt

Le caractère esperluette : &

Le caractères esperluette est vraiment très pratique car il permet de remplacer une chaîne de caractère par elle-même suivie ou précédée d'une autre chaîne de caractères.

echo -e "Le système Linux 2.6 est  génial" | sed 's/Linux/<B>&<\/B>/g'

Résultat :

Le système <B>Linux</B> 2.6 est  génial

Remarques :

Vous savez maintenant transformer toutes vos prises de notes en véritable site web !

Vous savez aussi convertir presque n'importe quel format texte non compilé en n'importe quel autre format !!!

Mais attention à la manipulation des caractères spéciaux car ceux-ci doivent toujours être précédés d'un backslash, regardez bien dans la deuxième balise </B> du script.

Vous savez aussi dériver n'importe quel radical avec un préfixe et/ou un suffixe !

Je vous laisse réfléchir un peu... puisque vous savez presque tout sur l'éditeur sed ! Complice

Mise à jour le Samedi, 29 Octobre 2011 16:35
 

La recherche de chaînes de caractères avec le filtre grep

Imprimer PDF

La commande grep est une des plus importantes pour nous. Vous constaterez sa présence dans la quasi totalité de mes scripts. C'est avec cet outil que nous allons mettre dans un flux les données d'un fichier texte les résultat de nos script avant de les rediriger dans un fichier texte.

  • Le filtre grep permet de trouver toutes les lignes d'un fichier texte dans lesquelles se trouve une chaîne de caractère recherchée.

Exemple :

Nous cherchons toutes les lignes dans lesquelles se trouve le mot renard dans le livre 1 des fables de la Fontaine au format .txt (la_fontaine_fables_livre1_oudry.txt) :

script :

grep renard la_fontaine_fables_livre1_oudry.txt

résultat :
...
Le renard s’en saisit et dit : « Mon bon Monsieur
...

Toutes les lignes contenant le mot renard serons renvoyées.

La commande grep possède de nombreuses options permettant d'affiner notre résultat dont voici les principales :

  • Ne pas tenir compte de la casse de la chaîne de caractère cherchée : -i

script :

grep -i renard la_fontaine_fables_livre1_oudry.txt

résultat :

Le Corbeau et le Renard ......................................................12
...
Le renard s’en saisit et dit : « Mon bon Monsieur
...

  • Renvoyer le contexte, c'est à dire la ligne avant, après ou les deux : -B1 -A1 -C1

script :

grep -A1 renard la_fontaine_fables_livre1_oudry.txt

résultat :

...
Le renard s’en saisit et dit : « Mon bon Monsieur
Apprenez que tout flatteur
...

Ici on pourrait écrire grep -A2 pour avoir les deux lignes suivantes, ou -A3 pour les troisièmes, etc... et idem pour l'option -B et -C.
Petite info au sujet de ces trois options : -A pour after, -B pour before et -C pour context.

script :

grep -C2 renard la_fontaine_fables_livre1_oudry.txt

résultat :

Et pour montrer sa belle voix
Il ouvre un large bec laisse tomber sa proie.
Le renard s’en saisit et dit : « Mon bon Monsieur
Apprenez que tout flatteur
Vit aux dépens de celui qui l’écoute

 

  • Renvoyer toutes les lignes sauf celles qui contiennent une chaîne de caractère donnée : -v


script :

grep -v cochonnerie commentaires_publiques.txt

résultat :

Toutes les lignes sauf celles qui contiennent la chaîne de caractère "cochonnerie" serons envoyées dans le flux.

 

  • Compter le nombre de lignes dans lesquelles se trouve une chaîne de caractères cherchée : -c


script :

grep -c renard la_fontaine_fables_livre1_oudry.txt

résultat :

13

 

  • Rechercher une expression exact : -w


Il est nécessaire de préciser que grep cherche la présence d'une chaîne de caractère qui elle même peut être présente dans une chaîne de caractère plus grande. Par exemple la chaîne « onde » est présente dans la chaîne « monde » et « ronde »...
Pour récupérer une chaîne de caractère exact nous utiliserons l'option w (word) :

script :

grep -w onde la_fontaine_fables_livre1_oudry.txt

résultat :

Dans le courant d’une onde pure.


L'option, -o de grep va faire écrire dans une colonne, autant de fois que la chaîne de caractère cherchée à été trouvée dans le texte. Nous verrons comment l'utiliser plus tard.

Ces options de grep sont les principales et nous donnent une bonne idée de ce qu'on peut faire avec ce filtre.  Maintenant, voyons ce qu'on peut faire avec cette commande poussée dans un niveaux un peu plus avancé :



La commande grep dans tous ses états :

Chercher plusieurs chaînes de caractères dans un texte :

script :

grep '\(renard\|corbeau\)' la_fontaine_fables_livre1_oudry.txt

résultat :

Toutes les lignes contenant la chaîne renard ou corbeau dans le texte la Fontaine seront envoyées dans le flux (donc sélectionnées). Vous pouvez ainsi mettre autant de mots que vous le souhaitez de cette manière dans grep.

Note : nous pouvons aisément ajouter toutes les options précédemment abordées à ce script, l'une n'empêche pas l'autre.

Remarques  :

 

  • Le petit bâtonnet (pipe) | mit entre les chaînes renard et corbeau fonctionne ici comme un OU logique.
  • Les backslash \ sont utilisés ici pour annuler la valeur des caractères spéciaux ( ) et | pour des raisons que nous aborderons plus tard.
  • Le caractère simple quote ' est utilisé ici pour délimiter un espace dans lequel nous faisons usage de caractères spéciaux.

 

Chercher une expression exact dans un texte :

script :

grep Maître\ renard la_fontaine_fables_livre1_oudry.txt

résultat :

Maître renard par l’odeur alléché


Seules les lignes contenant l'expression exact "Maître renard" sont acceptées, celles contenant maître ou renard ne sont pas retenues.

Remarques :

 

J'aurais due délimiter la chaîne Maître\ renard par des simple quotes, mais je ne l'ai pas fait par pure fainéantise, le résultat de ces deux variables étant les mêmes! Vous saurez désormais, que la fainéantise est une qualité requise chez l'informaticien qui cherchera toujours à systématiser le travail qu'il doit réaliser, dans l'unique but d'en faire le moins possible !

Chercher une chaîne de caractères qui commence par une ou un groupe de lettres en particulier :

Nous débutons enfin à traiter d'un sujet qui commence à avoir un rapport avec la recherche linguiste et psycholinguistique, notamment en ce qui concerne la création de bases de données de chaînes de caractères possédant certaines caractéristiques. De nombreuses recherches étudient par exemple, la manière nous traitons le début ou la fin d'un mot en situation de lecture.

Pour sélectionner une chaîne de caractère qui commence par une ou un groupe de lettres en particulier avec le filtre grep, nous utiliserons le caractère ^ (qui symbolise le début de ligne) .

script :

grep ^re la_fontaine_fables_livre1_oudry.txt

résultat :

recommandable ; ce sont qualités au-dessus de ma portée.
reconnaîtra dans cet auteur le vrai caractère et le vrai génie de
rendais nouvelles par quelques traits qui en relevassent le goût.
recommande aux nourrices de les leur apprendre ; car on ne
représentent confirme les personnes d’âge avancé dans les

Remarques importantes :

 

Comme je vous l'ai expliqué plus haut, la commande grep filtre les lignes qui contiennent une chaîne de caractères cherchée. Le résultat de ce script nous a renvoyé toutes les lignes qui commencent par le groupe de lettre re.

  • Pour obtenir l'ensemble des mots qui commence par le groupe de lettres re, nous seront obligés de faire appel à un autre outil : l'éditeur sed (que nous verrons plus tard).
  • Comme je vous l'ai promis, dans la « Présentation des outils Unix », le niveau de difficulté est croissant.
  • Je vais implémenter ici un « sous-script » avec sed qui va nous permettre d'obtenir l'ensemble des mots qui commence par le groupe de lettres re. La méthode est simple. Il suffit de remplacer tous les espaces entre les mots par un retour chariot. La conséquence de cette astuce est que chaque mot de chaque phrase sera écrits sur une ligne. Nous pourrons ensuite filtrer chaque ligne (dans laquelle ne se trouve qu'un seul mot)  qui commence par le groupe de lettres re.

Cette astuce fait partie des grands classiques des Unixiens chargés du traitement de l'information écrite.

Le script qui remplace chaque espace par un retour chariot :

 

script :

sed -e 's/\ /\n/g'

résultat :

Maître
corbeau,
sur
un
arbre
perché

Script final qui filtre tous les mots d'un texte qui commence par re :

script :

grep . la_fontaine_fables_livre1_oudry.txt |  sed -e 's/\ /\n/g | grep ^re

résultat :

recueil.
relâchât
remit
rend
reste
rendent
recommandable
reconnaîtra
rendais
relevassent
recommandable
rencontre
...

Remarques très importantes :

Il y a deux choses dont j'aurais due vous parler avant, mais je ne voulais pas vous embrouiller :

  • La première, le caractère . (le point) est un caractère générique pour grep qui symbolise tous les caractères.
  • La deuxième, le caractère | (le pipe) permet de rediriger le résultat d'un script dans un autre script.


Explications :

  • Les script « grep . la_fontaine_fables_livre1_oudry.txt » va mettre toutes les lignes du texte étudié dans un flux de données.
  • Le pipe ( | )va prendre ces données et les rediriger dans le script suivant ( sed -e 's/\ /\n/g) qui remplace tous les espaces par des retours chariots.
  • Le deuxième pipe ( | ) va rediriger ce nouveau flux de mots (alignés verticalement par sed) et l'envoyer dans le dernier script qui ne retient que les mots qui commencent par le groupe de lettres re.

 

Analogie de cet algorithme :

  • De nombreuses voitures roulent sur l'autoroute (le flux de mot = grep . ).
  • Les douanes à hauteur d'un péage (le pipe = | ) alignent toutes les voitures sur une voies ( remplacent les espaces par des retour chariots = sed -e 's/\ /\n/g') pour pouvoir les contrôler,
  • Elles interceptent uniquement les voitures rouges (les mots qui commencent par re = grep ^re) .

 

Chercher une chaîne de caractères qui commence par une ou un groupe de lettres en particulier :


Pour sélectionner une chaîne de caractère qui se termine par une ou un groupe de lettres en particulier avec le filtre grep, nous utiliserons le caractère $ (qui symbolise la fin de ligne). Par exemple, pour récupérer les chaînes de caractères qui se terminent par er nous utiliserons le script suivant :

script :

grep er$ la_fontaine_fables_livre1_oudry.txt

Remarques :

Nous ferons face exactement aux mêmes problèmes que précédemment, que nous résoudrons de la même manière :

script final :

grep . la_fontaine_fables_livre1_oudry.txt |  sed -e 's/\ /\n/g | grep er$

résultat :

appeler
marcher
habiller
m’empêcher
dernier
s’appliquer
attacher
envoyer
exiger
juger
considérer
porter
donner

Conclusions :

Le filtre grep est un trés bon outil de filtrage, donc de recherche de chaînes de caractères. Vous savez maintenant transformer votre ordinateur en moteur de recherche interne ! Vous êtes aussi aptes à comprendre ces scripts : http://www.lingunix.org/scripts-linguistiques-dictionnaires-banques-bibliotheques

Mise à jour le Jeudi, 31 Mars 2011 10:26