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
.
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, ...
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.
[adresse1 [,adresse2]] fonction [argument ...]
Une adresse est :
$
interprété comme l'adresse de la dernière ligne ;/
.
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
.
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.
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. |
sed -n '/^[0-9]\+$/p' fich.txt
motif
: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
.
Ecrire un script qui extrait le titre de toutes les pages html
.
On suppose le fichier suivant fich.txt
qui contient :
Marcel:Michu:16:55:09 Ghislaine:Verboten:56:13:29 Raymond:Calbuth:25:67:09
fich.txt
en majusculefich.txt
. Le caractère de séparation est :
.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
).
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
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
$> 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