# TP 5 1/2 - RegEx Ce TP donnera lieu à la remise d'un compte-rendu écrit exclusivement avec l'éditeur VI. ## Expressions rationnelles avec GREP Avant tout, pour que les ensembles `[a-z\]`... fonctionnent, lancez la commande `export LANG=C` dans le terminal. Rendez-vous, ensuite, dans le répertoire `/usr/include` où vous rechercherez, dans les fichiers `*.h` (dans le *contenu* des fichiers) les lignes correspondant aux motifs suivants : - Les lignes commençant par une minuscule. Une fois l'expression trouvée et testée vous vérifierez le résultat en ajoutant un tube et un second `grep` recherchant les lignes commençant par autre chose qu'une minuscule – normalement, vous ne devriez voir aucune ligne. Lors d'une recherche sur plusieurs fichiers, `egrep` ajoute à la sortie le nom du fichier. Supprimez cet affichage en utilisant `egrep -h`. egrep "^[a-z]" *.h affiche nom du fichier dans lequel la premiere ligne commence par .. -h n'affiche pas le nom du fichier -n affiche la ligne du fichier - Les lignes commençant par 3 lettres minuscules et se terminant par 3 caractères autres que des minuscules. egrep -h "^[a-z]{3}.*[^a-z]{3}$" *.h - Les lignes ne contenant aucune majuscule. Une fois l'expression trouvée, vous ferez comme en A pour vérifier votre résultat. egrep -h "^[^A-Z]+$" *.h n'affiche pas les lignes vides avec + egrep -h "^[^A-Z]*$" *.h affiche les lignes vides avec * - La commande *grep* associée à l'option « *-v* » permet d'afficher les lignes ne répondant pas au motif (sélection inverse). Recherchez les lignes ne contenant pas le mot «*printf* ». Comme en A et C, vérifiez votre résultat. egrep -hv "printf" *.h - Les lignes comprenant trois caractères, a, b, c, d ou e identiques à la suite (aaa, eee ....) egrep -h "([a-z])\1\1\1" *.h egrep -h "([a-z])\1{2}" *.h - Les lignes comprenant un nombre entier d'au moins 8 chiffres. Pour ce faire, veillez à ce que le motif reconnu soit bien un nombre, à savoir une suite de chiffres autour de laquelle on trouve un séparateur : espace, fin de ligne, = .... egrep -h "[0-9]{8,}" *.h on a tout egrep -h "[( x=]+[0-9]{8,}[^a-zA-Z]" *.h on affine notre recherche donc on en perd. un nb qui terminait la ligne est perdu. - En utilisant les blocs et rappels de blocs, identifiez les lignes contenant un même mot au moins 3 fois. Un mot est défini comme une suite de lettres autour de laquelle il y a autre chose que des lettres. Les mots peuvent être séparés les uns des autres par d'autres mots. egrep -h "([a-zA-Z]{5,}).*\1.*\1" *.h egrep -hn "[ (;,]([a-zA-Z]{5,})[ (;,].*\1.*\1" *.h egrep -hn "\b([a-zA-Z]{15,})\b.*\b\1.*\b\1\b" *.h - Les lignes contenant un nombre compris entre 400 et 450. (450 exclu) egrep -hn "[^0-9]4[0-4][0-9][^0-9]" *.h egrep -hn "[ ]4[0-4][0-9][ ]" *.h egrep -hn "\b4[0-4][0-9]\b" *.h - Les lignes contenant un nombre réel (suite de chiffres incluant un et 1 seul point) egrep -hn "[^.a-zA-Z0-9][0-9]+\.[0-9]+[^.a-zA-Z0-9]" *.h egrep -hn "[ ][0-9]+\.[0-9]+[ ]" *.h ## Application des expressions rationnelles à SED SED permet d'utiliser des expressions rationnelles sur un flux d'entrée de données, tout en utilisant une syntaxe proche de celle de VI. Un des intérêts de SED est d'utiliser la syntaxe rechercher/remplacer. Par exemple : `sed -re 's/titi/toto/g < donnees.txt` va afficher le contenu de **donnees.txt** en remplaçant chaque occurrence de **titi** par **toto**. Il est bien entendu possible d'utiliser des expressions rationnelles. sed -re 's/titi/toto/g' < donnees.txt sed -re 's/[to]+/ti/g' < donnees.txt Nous souhaitons modifier un fichier de configuration de type xml pour la réalisation d'une procédure d'installation automatisée (imaginez que le problème qui va vous être décrit existe dans plusieurs miliers de fichiers); copiez le texte suivant dans un fichier `config.xml`. ~~~xml String xxxxxx String xxxxxx ~~~ - Constatez que le fichier contient un bug : *valu* est écrit parfois sans « e ». À l'aide de la commande `sed` corrigez toutes ces erreurs et enregistrez le résultat dans `fichier.A.xml`. - Il s'agit maintenant, dans le fichier obtenu de remplacer la première des chaînes `xxxxxx` par votre login puis la seconde par votre nom de famille. - Essayez de faire les remplacements à l'aide de la commande `sed `. Quelle difficulté rencontrez-vous ? - Comme vous l'avez constaté, `sed ` fonctionne ligne à ligne, il est donc nécessaire de transformer ce texte en une seule ligne. Nous utiliserons un caractère pour remplacer les retours chariot de sorte que l'opération inverse soit possible à la fin. La commande `tr ` permet de remplacer un caractère par une autre. Transformer les retours chariot « `\n ` » par un « `# ` ». - À l'aide de la commande `sed ` réalisez la recherche et le remplacement du login L'utilisation des blocs est nécessaire : Un premier bloc débute devant la chaine « `**` » et se termine après « `**` » ; le second va de « `**` » à « `**` ». - À l'aide de la commande `sed ` réalisez la recherche et le remplacement du nom ; combinez ensuite les deux commandes. - À l'aide de la commande `tr ` restaurez les sauts de lignes puis enregistrez le résultat dans un fichier `config.new.xml `. #### 3 – Autres applications avec SED - Réécrivez avec `sed` la commande `tr -s ' '` qui supprime les espaces multiples. sed -re 's/ +/ /g' - Écrivez avec `sed` une commande permettant de supprimer les espaces en début de ligne. sed -re 's/^ +//g' -e 's/ +/ /g'