On a vu auparavant ce qu'étaient les métacaractères. Les expressions régulières sont aussi des suites de caractères permettant de faire des sélections. Elles fonctionnent avec certaines commandes comme grep.
Les différentes expressions régulières sont :
Exemple l'expression [a-z][a-z] * cherche les lignes contenant au minimum un caractère en minuscule. [a-z] caractère permis, [a-z]* recherche d'occurrence des lettres permises.
L'expression [0-9]\ {4\}$ a pour signification, du début à la fin du fichier $, recherche les nombres[0-9] de 4 chiffres \ {4\}.
La commande grep permet de rechercher une chaîne de caractères dans un fichier. Les options sont les suivantes :
Exemple avec le fichier carnet-adresse :
olivier:29:0298333242:Brest
marcel:13:0466342233:Gardagnes
myriam:30:0434214452:Nimes yvonne:92:013344433:Palaiseau
On peut utiliser les expressions régulières avec grep. Si on tape la commande :
grep ^[a-d] carnet-adresse
On va obtenir tous les lignes commençant par les caractères compris entre a et d. Dans notre exemple, on n'en a pas, d'où l'absence de sortie.
grep Brest carnet-adresse
Permet d'obtenir les lignes contenant la chaîne de caractère Brest, soit :
olivier:29:0298333242:Brest
Il existe aussi les commandes fgrep et egrep équivalentes.
La commande find permet de retrouver des fichiers à partir de certains critères. La syntaxe est la suivante :
find <répertoire de recherche> <critères de recherche>
Les critères de recherche sont les suivants :
On peut combiner les critères avec des opérateurs logiques :
La commande find doit être utilisé avec l'option -print. Sans l'utilisation de cette option, même en cas de réussite dans la recherche, find n'affiche rien à la sortie standard (l'écran, plus précisément le shell).
La commande find est récursive, c'est à dire où que vous tapiez, il va aller scruter dans les répertoires, et les sous répertoires qu'il contient, et ainsi de suite.
Pour chercher un fichier dont le nom contient la chaîne de caractères toto à partir du répertoire /usr, vous devez tapez :
find /usr -name toto -print
En cas de réussite, si le(s) fichier(s) existe(nt), vous aurez comme sortie :
toto
En cas d'échec, vous n'avez rien.
Pour rechercher tous les fichiers se terminant par .c dans le répertoire /usr, vous taperez :
find /usr -name " *.c " -print
Vous obtenez toute la liste des fichiers se terminant par .c sous les répertoires contenus dans /usr (et dans /usr lui même).
Pour connaître les derniers fichiers modifiés dans les 3 derniers jours dans toute l'arborescence (/), vous devez taper :
find / -mtime 3 -print
Recherche suivant la taille
Pour connaître dans toute l'arborescence, les fichiers dont la taille dépasse 1Mo (2000 blocs de 512Ko), vous devez taper :
find / -size 2000 -print
Vous pouvez chercher dans toute l'arborescence, les fichiers ordinaires appartenant à olivier, dont la permission est fixée à 755, on obtient :
find / -type f -user olivier -perm 755 -print
Vous vous rendrez compte assez rapidement qu'en tant que simple utilisateur, vous n'avez pas forcément le droit d'accès à un certain nombre de répertoires, par conséquent, la commande find peut générer beaucoup de messages d'erreur (du genre permission denied), qui pourraient noyer l'information utile. Pour éviter ceci, vous pouvez rediriger les messages d'erreur dans un fichier poubelle (comme /dev/null), les messages d'erreur sont alors perdus (rien ne vous empêche de les sauvegarder dans un fichier, mais ça n'a aucune utilité avec la commande find).
find . -name bobo -print 2>/dev/null
Recherche en utilisant les opérateurs logiques
Si vous voulez connaître les fichiers n'appartenant pas à l'utilisateur olivier, vous taperez :
find . ! -user olivier -print
! -user olivier, est la négation de -user olivier, c'est à dire c'est tous les utilisateurs sauf olivier. Recherche des fichiers qui ont pour nom a.out et des fichiers se terminant par .c. On tape : find . \ ( -name a.out -o -name " *.c " \ ) -print
On recherche donc les fichiers dont le nom est a.out ou les fichiers se terminant par *.c, une condition ou l'autre.
Recherche des fichiers qui obéissent à la fois à la condition a pour nom core et à la condition a une taille supérieure à 1Mo.
find . \ (-name core -a size +2000 \ ) -print
L'option -print est une commande que l'on passe à find pour afficher les résultats à la sortie standard. En dehors de print, on dispose de l'option -exec. find couplé avec exec permet d'exécuter une commande sur les fichiers trouvés d'après les critères de recherche fixés. Cette option attend
comme argument une commande, celle ci doit être suivi de {}\ ;.
Exemple recherche des fichiers ayant pour nom core, suivi de l'effacement de ces fichiers.
find . -name core -exec rm {}\ ;
Tous les fichiers ayant pour nom core seront détruits, pour avoir une demande de confirmation avant l'exécution de rm, vous pouvez taper :
find . -name core -ok rm {}\ ;
Une fonction intéressante de find est de pouvoir être utilisé avec d'autres commandes UNIX. Par exemple:
find . -type f -print | xargs grep toto
En tapant cette commande vous allez rechercher dans le répertoire courant tous les fichiers normaux (sans les répertoires, fichiers spéciaux), et rechercher dans ces fichiers tous ceux contenant la chaîne toto.
Une expression régulière (en anglais Regular Expression ou RE) sert à identifier une chaîne de caractère répondant à un certain critère (par exemple chaîne contenant des lettres minuscules uniquement). L'avantage d'une expression régulière est qu'avec une seule commande on peut réaliser un grand nombre de tâche qui seraient fastidieuses à faire avec des commandes UNIX classiques. Les commandes ed, vi, ex, sed, awk, expr et grep utilisent les expressions régulières.
L'exemple le plus simple d'une expression régulière est une chaîne de caractères quelconque toto par exemple. Cette simple expression régulière va identifier la prochaine ligne du fichier à traiter contenant une chaîne de caractère correspondant à l'expression régulière.
Si l'on veut chercher une chaîne de caractère au sein de laquelle se trouve un caractère spécial (/, *,
$, ., [, ], {, }, !, entre autres) (appelé aussi métacaractère), on peut faire en sorte que ce caractère ne soit pas interprété comme un caractère spécial mais comme un simple caractère. Pour cela vous devez le faire précéder par \ (backslash). Ainsi si votre chaîne est /dev, pour que le / ne soit pas interprété comme un caractère spécial, vous devez tapez \ /dev pour l'expression régulière.
Le métacaractère . remplace dans une expression régulière un caractère unique, à l'exception du caractère retour chariot (\ n). Par exemple chaine. va identifier toutes les lignes contenant la chaine chaine suivit d'un caractère quelconque unique. Si vous voulez identifier les lignes contenant la chaîne .cshrc, l'expression régulière correspondante est \ .cshrc
On trouve les variables système et les variables utilisateurs. Les variables systèmes non modifiables donnent des informations sur le déroulement du programme. Les variables utilisateurs sont définies par l'utilisateur.
Le nom des variables est formé de lettres, de chiffres (sauf le premier caractère de la variable), d'underscore. Ce n'est pas nécessaire d'initialiser une variable, par défaut, si c'est un numérique, elle est égale à 0, si c'est une chaîne, elle est égale à une chaîne vide. Une variable peut contenir du texte, puis un chiffre, en fonction de son utilisation awk va déterminer son type (numérique ou chaîne).
Les variables prédéfinies sont les suivantes (en italique les valeurs par défaut):
On peut manipuler les variables et leur faire subir certaines opérations. On trouve différents types d'opérateurs, les opérateurs arithmétiques classiques (+, -, *, /, %(modulo, reste de la division), (puissance)), les opérateurs d'affectation (=, +=, -=, *=, /=, %=, =). Exemples:
Comme on l'a déjà vu auparavant les champs d'un enregistrement (ligne) sont désignés par $1,
$2,...$NF(dernier champ d'une ligne). L'enregistrement complet (ou ligne) est désigné par $0. Une variable champ est a les mêmes propriétés que les autres variables. Le signe $ peut être suivi par une variable, exemple:
i=3
print $(i+1)
Provoque l'affichage du champ 4
Lorsque $0 est modifié, automatiquement les variables de champs $1,..$NF sont redéfinies.
Quand l'une des variables de champ est modifée, $0 est modifié. ATTENTION le séparateur ne sera pas celui définit par FS mais celui définit par OFS (output field separator). Exemple:
awk 'BEGIN{print" # Tous les utilisateurs du groupe users(GID 22)basculeront dans le groupe boulot(GID 24)
";FS=":";OFS=":"}
$4 != 22 {print $0} # Si le groupe n'est pas users on fait rien
$4 ==22 {$4=24;print $0} # Si le groupe est 22, on lui réaffecte 24 END {print"C'est fini"}' /etc/passwd > passwd.essai
Parmi les structures de contrôle, on distingue les décisions (if, else), les boucles (while, for, do- while, loop) et les sauts (next, exit, continue, break).
Les décisions (if, else)
La syntaxe est la suivante:
if (condition) si la condition est satisfaite (vraie) instruction1 on exécute l'instruction
else sinon
instruction2 on exécute l'instruction 2
Si vous avez une suite d'instructions à exécuter, vous devez les regrouper entre deux accolades. Exemple:
awk ' BEGIN{print"test de l'absence de mot de passe";FS=":"} NF==7
{ #pour toutes les lignes contenant 7 champss
if ($2=="") # si le deuxième champ est vide (correspond au mot de passe crypté))
{ print $1 " n'a pas de mot de passe"} # on affiche le nom de l'utilisateur ($1=login) qui n'a pas de mot de passe
else sinon
{ print $1 " a un mot de passe"} # on affiche le nom de l'utilisateur possédant un mot de passe
}
END{print"C'est fini") ' /etc/passwd
Les boucles (while, for, do-while)
while, for et do-while sont issus du langage de programmation C. La syntaxe de while est la suivante:
while (condition) tant que la condition est satisfaite (vraie) instruction on exécute l'instruction