Table des matières

Expressions régulières

Le but de TD est de faire l'apprentissage de la manipulation des expressions régulières. Cet apprentissage s'illustrera au travers de deux outils sed et grep.

Rappels sur les expressions régulières

Début de ligne                           : ^
Fin de ligne                             : $
N'importe quel caractère                 : .
Zéro ou une occurrence                   : ?
Zéro ou plusieurs occurrences            : *
Une ou plusieurs occurrences             : +
Exactement 'n' occurrences               : {n}
Au moins 'n' occurrences                 : {n,}
Entre n et m occurrences                 : {m,n}
'a' ou 'b' ou 'c'                        : a|b|c
Ensemble de caractères {a, b, c}         : [abc]
Ensemble de caractères {a, ..., z }      : [a-z]
Caractère n'appartenant pas à l'ensemble : [^...]
Regroupement et capture de caractères.   : (...)
Références à des regroupements.          : \1, \2, ...

Rappel sur SED

Il s'agit d'un éditeur ne travaillant pas en mode interactif. Les fichiers édités ne sont pas modifiés : leur contenu est simplement utilisé pour construire un flux sur la sortie standard. A ce titre sed est un filtre pour le bash.

sed [-n] [-e command_sed] [-f file_com] [ref ...]

… a pour effet de copier le (ou les fichiers) sources ref sur la sortie standard après application aux lignes complètes du fichier (c'est-à-dire contenant un caractère de fin de ligne) de toutes les commandes contenues dans le fichier file_com et les différentes commandes introduites en paramètres par un argument -e (-e est l'option par défaut). Par défaut, le fichier traité est l'entrée standard.

Forme générale des commandes

[adresse1 [,adresse2]] fonction [argument ...]

Une adresse est :

Intervalle concerné : adresse1, adresse2 (par défaut, tout le fichier sera traité). On peut imbriquer les commandes afin de les appliquer à une même adresse, on utilise alors \{ et \} aprés adresse.

Le fonctionnement

sed maintient un tampon de travail où chaque ligne est successivement chargée et toutes les commandes qui la concernent (adresse1, adresse2) lui sont appliquées, après quoi la ligne est écrite sur la sortie standard (sauf si -n a été donné au chargement, auquel cas seules les commandes explicites d'impression provoqueront une impression). Quand toutes les instructions ont été appliquées, la ligne courante est affichée et la ligne suivante est placée dans le tampon de travail.

Les fonctions

nb adr commande actions
[0] # texte commentaire jusque la fin de ligne
[1] a\ texte concaténation du texte avant de lire la ligne suivante
[2] c\ texte suppression de l'espace de travail correspondant à l'intervalle et écriture du texte sur la sortie.
[2] d suppression de l'espace de travail. Exemple : sed /toto/d file supprime les lignes contenant toto dans file
[2] D suppression de l'espace de travail jusqu'au premier caractère de fin de ligne (précédé du caractère \ qu'il contient)
[1] i\ texte insertion du texte sur la sortie standard
[2] p écrit l'espace de travail sur la sortie standard. Exemple : sed} -n /toto/p file n'écrit que les lignes de file contenant toto
q terminaison
[2] r file écrit le contenu de file avant de continuer
[2] s/regexpr/ chaine/ind substitution d'un motif à un autre défini au moyen d'expressions régulières. Les indicateurs sont g : toutes les occurrences, p : écrit si une substitution a été effectuée, w file : écriture dans file. Le contenu est concaténé si une substitution a été effectué.
[2] w file écrit l'espace de travail dans file.
[2] y/chaine1/chaine2 toutes les occurrences des caractères figurant dans chaine1 sont remplacées par le caractère correspondant (c'est-à-dire en même position) de chaine2.
[2] ! commande exécution de la commande sur les lignes dont l'adresse n'est pas dans l'intervalle.
[2] = Donne le numéro de la ligne sélectionnée sur la sortie standard.

Un peu d'entraînement

    sed -n '/^[0-9]\+$/p' fich.txt
    echo aabbabbaab | sed $motif
    motif='s/[ab]*/x/'
    motif='s/a.*b/y/'
    motif='s/a.*bb/z/'
    motif='s/a\?b/z/g'
    motif='s/aab\|ba\|bba/ab/g'
    echo "ejkf fed 158e fd" | sed 's/[^0-9]*\([0-9]\+\)[^0-9]*/\1/
    echo "ejkf fed 158e fd" | sed 's/.*\([0-9]\+\).*/\1/' 

Réécrire la commande head en utilisant sed.

HTML

Ecrire un script qui extrait le titre de toutes les pages html.

A partir d'un fichier ...

On suppose le fichier suivant fich.txt qui contient :

    Marcel:Michu:16:55:09
    Ghislaine:Verboten:56:13:29
    Raymond:Calbuth:25:67:09

DATE

La fonction date renvoie un résultat de la forme suivante :

    jeu jan 26 17:26:47 CET 2019

Ecrivez une commande, en utilisant date et sed, permettant d'obtenir le résultat suivant :

    Nous sommes le jeu 26 jan 2019 et il est 17:26:47.

Ecrire la commande grep permettant de récupérer dans le fichier fich.txt les lignes contenant des heures valides (format hh:mm:ss).

Un peu de GREP

Que font les commandes suivantes ? ([ ] contient un espace et une tabulation) :

    grep -E -c '^[      ]*$' fich.txt
    grep -E -c '^[^      ]+$' fich.txt
    grep -E -c '[^      ]' fich.txt
    grep -E -n -v '[^      ]+$' fich.txt

Lister des fichiers

La commande ls -l produit la sortie suivante

    drwxr-xr-x  4 gilles  staff  128 22 jan 11:41 dir-1
    drwxr-xr-x  2 gilles  staff   64 22 jan 14:41 dir-2
    -rw-r--r--  1 gilles  staff    0 22 jan 22:39 file-1
    -rw-r--r--  1 gilles  staff    0 22 jan 08:18 file-2
    -rw-r--r--  1 gilles  staff    0 22 jan 07:03 mon-script-exemple.sh
    dir-1 modifie a 11:41
    dir-2 modifie a 14:41
    file-1 modifie a 22:39
    file-2 modifie a 08:18
    mon-script-exemple.sh modifie a 07:03

Liste des extensions

    $> ls
    abc  ab.o  ab.tar.gz  a.c  a.o  bcabdc.c  ccabdc.zip

Ecrivez la commande permettant d'obtenir l'affichage suivant :

    .c
    .gz
    .o
    .zip