$ carnet-linux
PHASE 2 · MODULE 06

Rechercher & expressions régulières

Retrouver n'importe quel fichier en une commande, savoir où se cache un programme, et décrire du texte avec des motifs : les expressions régulières, l'outil qui transforme grep en détecteur surpuissant.

⏱️ Lecture ~50 min 🧪 Pratique ~1 h 30 🎚️ Niveau intermédiaire
Tux

🎯 Ce que tu sauras à la fin

🔦

find

Chercher par nom, type, taille, date, propriétaire… et agir.

⚡

locate & which

Trouver instantanément un fichier ou une commande.

🧩

Regex

Lire et écrire des expressions régulières.

🔗

xargs

Passer une liste de résultats à n'importe quelle commande.

Retrouver un fichier avec find

▶ Vidéo · 1 min 30find : retrouver n'importe quel fichieroù chercher, quoi chercher, quoi en faire
Animation réalisée pour ce cours. Voix off et musique générées par IA (Google Gemini et Lyria).

find parcourt réellement l'arborescence, dossier par dossier. Sa grammaire répond à trois questions :

findla commande
/etcoù chercherdossier de départ
-name "*.conf"quoi cherchercritères
-lsquoi en faireaction (affiche par défaut)

Les critères

CritèreTrouveExemple
-name / -inamePar nom (jokers permis), -iname ignore la casse-name "*.log"
-type f / d / lFichiers / dossiers / liens symboliques-type d
-sizePar taille : + plus de, - moins de (k, M, G)-size +100M
-mtime / -mminModifiés il y a moins (-) ou plus (+) de N jours / minutes-mtime -7
-user / -groupPar propriétaire / groupe-user www-data
-permPar droits-perm -4000 (bit SUID)
-emptyFichiers ou dossiers vides-type d -empty
-maxdepth NNe descend pas à plus de N niveaux (à placer en premier)-maxdepth 1

Plusieurs critères se combinent par un ET implicite. Pour un OU : -o ; pour une négation : ! (ou -not), avec des parenthèses échappées pour grouper : \( … \).

user@ubuntu:~$ find /etc -name "*.conf" 2>/dev/null | head -3
/etc/adduser.conf
/etc/ca-certificates.conf
/etc/debconf.conf
user@ubuntu:~$ sudo find / -type f -size +100M 2>/dev/null      # les gros fichiers du disque
/swap.img
/var/lib/snapd/snaps/gnome-42-2204_202.snap
user@ubuntu:~$ find ~ -type f -mtime -1                        # modifiés depuis 24 h
user@ubuntu:~$ find ~/labo \( -name "*.log" -o -name "*.txt" \)     # .log OU .txt
Guillemets obligatoires autour des jokers

Sans guillemets, le shell remplace *.conf par les fichiers du dossier courant avant même que find ne démarre. Avec "*.conf", c'est find qui reçoit le motif et l'applique dans chaque dossier. Écris toujours -name "…".

Les actions

ActionEffet
-printAffiche le chemin (action par défaut)
-lsAffiche les détails, comme ls -l
-exec cmd {} \;Lance cmd une fois par résultat ({} = le chemin trouvé)
-exec cmd {} +Lance cmd une seule fois avec tous les résultats : beaucoup plus rapide
-ok cmd {} \;Comme -exec, mais demande confirmation à chaque fois
-deleteSupprime les résultats. Sans corbeille.
user@ubuntu:~$ find ~/labo -name "*.sh" -exec chmod u+x {} +       # rendre tous les scripts exécutables
user@ubuntu:~$ find /tmp -user $USER -name "*.tmp" -mtime +7        # 1. vérifier la liste…
user@ubuntu:~$ find /tmp -user $USER -name "*.tmp" -mtime +7 -delete  # 2. …puis supprimer
Toujours lister avant -delete

Lance la recherche une première fois sans action, lis la liste, puis seulement ajoute -delete à la fin. Placé avant les critères, -delete s'appliquerait à tout ce que find rencontre.

Plus rapide : locate, which et compagnie

find lit le disque à chaque fois. locate, lui, interroge une base de données de tous les noms de fichiers, mise à jour une fois par jour : la réponse est instantanée, mais les fichiers créés depuis la dernière mise à jour n'y figurent pas.

user@ubuntu:~$ sudo apt install plocate          # la version moderne de locate
user@ubuntu:~$ locate sshd_config
/etc/ssh/sshd_config
/usr/share/man/man5/sshd_config.5.gz
user@ubuntu:~$ sudo updatedb                     # mettre la base à jour tout de suite
CommandeRépond àExemple
whichQuel programme sera lancé si je tape ce nom ?which python3 → /usr/bin/python3
type -aEst-ce un alias, une primitive, un programme ? Tous les emplacementstype -a ls
whereisOù sont le programme, ses sources et sa page de manuel ?whereis bash
command -vComme which, en version portable pour les scriptscommand -v git || echo "absent"
Quel outil choisir ?

Un fichier dont tu connais à peu près le nom : locate. Des critères précis (taille, date, droits) ou des fichiers tout récents : find. Une commande : which ou type. Un mot à l'intérieur des fichiers : grep -r.

Les expressions régulières

▶ Vidéo · 1 min 30Les expressions régulières en 90 secondesancres, classes, quantificateurs
Animation réalisée pour ce cours. Voix off et musique générées par IA (Google Gemini et Lyria).

Une expression régulière (regex) décrit une forme de texte plutôt qu'un mot précis : « une ligne qui commence par un chiffre », « une adresse e-mail », « un code postal de 5 chiffres ». On les utilise avec grep, sed, awk, les éditeurs et presque tous les langages.

Les briques de base

SymboleSignifieExempleCorrespond à
^Début de ligne^root« root » en tout début de ligne
$Fin de lignebash$lignes qui finissent par « bash »
.N'importe quel caractère (un seul)c.tcat, cot, c-t, c4t…
*L'élément précédent, 0 fois ou plusab*cac, abc, abbbc…
[abc]Un caractère de la liste[Ll]inuxLinux, linux
[a-z], [0-9]Un caractère de l'intervalle[0-9][0-9]deux chiffres consécutifs
[^…]Un caractère absent de la liste[^0-9]tout sauf un chiffre
\Annule le sens spécial\.un vrai point

Le mode étendu : grep -E

SymboleSignifieExemple
+1 fois ou plus[0-9]+ : un nombre
?0 ou 1 fois (facultatif)https? : http ou https
{n}, {n,m}Exactement n fois, entre n et m fois[0-9]{5} : code postal
a|ba OU berror|fail
( )Grouper(ab)+ : ab, abab…

Classes prédéfinies, valables dans toutes les langues (accents compris) : [[:digit:]] (chiffre), [[:alpha:]] (lettre), [[:alnum:]] (lettre ou chiffre), [[:space:]] (espace, tabulation), [[:upper:]], [[:lower:]].

user@ubuntu:~$ grep '^root' /etc/passwd                     # commence par root
root:x:0:0:root:/root:/bin/bash
user@ubuntu:~$ grep -c 'nologin$' /etc/passwd              # combien de comptes sans shell ?
33
user@ubuntu:~$ grep -v '^#' /etc/adduser.conf | grep -v '^$'   # config sans commentaires ni lignes vides
user@ubuntu:~/labo$ grep -Eo '^([0-9]{1,3}\.){3}[0-9]{1,3}' acces.log | sort -u
10.0.0.5
172.16.0.8
192.168.1.10
192.168.1.22

L'option -o n'affiche que la partie qui correspond, pas toute la ligne : idéal pour extraire des informations.

Jokers du shell ≠ expressions régulières

Les deux utilisent *, ? et [ ], mais pas avec le même sens :

Joker du shell (ls *.txt)Regex (grep)
*n'importe quelle suite de caractèresl'élément précédent, répété
?un caractèrel'élément précédent, facultatif (en -E)
.un vrai pointn'importe quel caractère

« N'importe quoi » s'écrit * en joker, mais .* en regex. Et entoure toujours un motif de regex d'apostrophes '…' pour que le shell n'y touche pas.

Les regex dans sed et awk

user@ubuntu:~$ echo "Tel : 06 12 34 56 78" | sed -E 's/[0-9]{2} [0-9]{2}$/XX XX/'
Tel : 06 12 34 XX XX
user@ubuntu:~$ echo "2026-10-24" | sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/'
24/10/2026                                         # \1 \2 \3 : les groupes capturés
user@ubuntu:~/labo$ awk '/POST/ {print $1}' acces.log | sort -u      # awk filtre aussi par regex
10.0.0.5

Chercher dans les fichiers : grep -r

user@ubuntu:~$ grep -rn "PermitRootLogin" /etc/ssh/ 2>/dev/null
/etc/ssh/sshd_config:33:#PermitRootLogin prohibit-password
user@ubuntu:~$ grep -rl "TODO" ~/projet --include="*.sh"       # -l : seulement les noms de fichiers
user@ubuntu:~$ grep -rw "listen" /etc --exclude-dir=ssl 2>/dev/null

Passer des résultats à une commande : xargs

Certaines commandes ne lisent pas leur entrée standard : rm, cp, chmod attendent des arguments. xargs fait le pont : il lit une liste sur stdin et la transforme en arguments.

user@ubuntu:~/labo$ find . -name "*.log" | xargs wc -l          # compter les lignes de tous les .log
user@ubuntu:~/labo$ find . -name "*.tmp" -print0 | xargs -0 rm     # sûr même avec des espaces dans les noms
user@ubuntu:~$ echo "un deux trois" | xargs -n1                  # un argument par commande
un
deux
trois
user@ubuntu:~$ ls *.txt | xargs -I{} cp {} {}.bak               # -I{} : placer l'argument où l'on veut
Les noms avec des espaces

Par défaut, xargs découpe aux espaces : « Mes Documents » deviendrait deux arguments. Le duo find -print0 | xargs -0 sépare les noms par un caractère nul, impossible dans un nom de fichier : c'est la version robuste. find -exec … {} + fait souvent le même travail plus simplement.

Glossaire du module

find
Recherche de fichiers par critères, en parcourant le disque.
locate / updatedb
Recherche instantanée dans une base de noms, mise à jour par updatedb.
which / type
Indiquent quel programme correspond à une commande.
Expression régulière
Motif qui décrit une forme de texte.
Ancre
^ (début) et $ (fin de ligne).
Classe
Ensemble de caractères entre crochets : [0-9], [[:alpha:]].
Quantificateur
Nombre de répétitions : *, +, ?, {n,m}.
BRE / ERE
Regex de base (grep) / étendues (grep -E, sed -E).
Groupe capturé
Partie entre parenthèses, réutilisable avec \1, \2…
xargs
Transforme une liste reçue sur stdin en arguments de commande.

🧠 Quiz : as-tu tout retenu ?

1. Quelle commande trouve les dossiers vides sous ~/labo ?
Sans -type d, on obtiendrait aussi les fichiers vides.
2. Pourquoi mettre "*.conf" entre guillemets dans find -name ?
Sans guillemets, le shell développe *.conf dans le dossier courant.
3. locate ne trouve pas un fichier créé il y a une minute. Pourquoi ?
sudo updatedb met la base à jour immédiatement.
4. Que trouve la regex ^[0-9] ?
^ ancre au début de ligne (attention : à l'intérieur des crochets, [^0-9] signifie « pas un chiffre »).
5. En regex, comment écrire « n'importe quoi » ?
. = un caractère quelconque, * = répété. Le * seul est le joker du shell.
6. Avec grep -E, que reconnaît [0-9]{5} ?
{5} répète l'élément précédent exactement 5 fois : parfait pour un code postal.
7. Que fait l'option -o de grep ?
C'est -v qui inverse. -o sert à extraire.
8. Pourquoi find … -print0 | xargs -0 plutôt que find … | xargs ?
Le caractère nul sépare les noms sans ambiguïté.
Réponds aux questions pour voir ton score.

🚀 Mission pratique

Pour les exercices sur les expressions régulières, crée d'abord ce fichier de contacts (fictifs) :

user@ubuntu:~$ mkdir -p ~/labo && cat > ~/labo/contacts.txt << 'FIN'
Alice Martin;alice.martin@exemple.fr;06 12 34 56 78;Paris
Bob Durand;bob@mail.com;07 98 76 54 32;Lyon
Chloé Petit;chloe.petit@exemple.fr;01 23 45 67 89;Paris
David Leroy;david.leroy(at)mail.com;0612345678;Marseille
Emma Roux;emma.roux@exemple.org;06-11-22-33-44;Lille
FIN

À faire dans la machine virtuelle

Coche chaque étape une fois faite : sa correction s'affiche juste en dessous.

  • ✅ Correction
    $ find /etc -maxdepth 1 -name "*.conf" | wc -l
    31

    Le nombre exact dépend des paquets installés. -maxdepth 1 doit être placé avant les autres critères.

  • ✅ Correction
    $ sudo find /var -type f -size +10M -exec ls -lhS {} + 2>/dev/null | head -5
    # ou, avec du et sort :
    $ sudo find /var -type f -exec du -h {} + 2>/dev/null | sort -hr | head -5

    On y trouve en général les paquets en cache (/var/cache/apt), les snaps et les journaux.

  • ✅ Correction
    $ find ~ -type f -mmin -60 2>/dev/null

    Tu y verras les fichiers que tu viens de créer, et ceux que GNOME ou le navigateur modifient en permanence (dans ~/.cache, ~/.config).

  • ✅ Correction
    $ find /usr/bin -perm -4000
    /usr/bin/passwd
    /usr/bin/sudo
    /usr/bin/su
    /usr/bin/mount
    ...

    Ce sont les programmes qui s'exécutent avec les droits de root : les auditeurs de sécurité vérifient toujours cette liste.

  • ✅ Correction
    $ sudo apt install plocate
    $ touch ~/labo/introuvable.txt
    $ locate introuvable.txt
    # aucun résultat : la base date d'avant la création
    $ sudo updatedb
    $ locate introuvable.txt
    /home/user/labo/introuvable.txt
  • ✅ Correction
    $ which ls
    /usr/bin/ls
    $ type -a ls
    ls est un alias vers « ls --color=auto »
    ls est /usr/bin/ls
    ls est /bin/ls
    $ whereis ls
    ls: /usr/bin/ls /usr/share/man/man1/ls.1.gz

    which ne voit pas l'alias ; type -a montre tout, y compris /bin/ls qui est le même fichier via le lien /bin → usr/bin.

  • ✅ Correction
    $ cd ~/labo
    $ grep 'Paris$' contacts.txt
    Alice Martin;alice.martin@exemple.fr;06 12 34 56 78;Paris
    Chloé Petit;chloe.petit@exemple.fr;01 23 45 67 89;Paris
    $ grep 'exemple\.fr' contacts.txt | cut -d';' -f1
    Alice Martin
    Chloé Petit

    Le \. désigne un vrai point : sans l'antislash, . accepterait n'importe quel caractère.

  • ✅ Correction
    $ grep -Eo '[[:alnum:]._-]+@[[:alnum:].-]+\.[a-z]{2,}' contacts.txt
    alice.martin@exemple.fr
    bob@mail.com
    chloe.petit@exemple.fr
    emma.roux@exemple.org

    L'adresse de David, écrite avec (at), n'est pas reconnue : c'est voulu.

  • ✅ Correction
    $ grep -E ';0[67]( [0-9]{2}){4};' contacts.txt | cut -d';' -f1,3
    Alice Martin;06 12 34 56 78
    Bob Durand;07 98 76 54 32

    Le numéro de David (sans espaces) et celui d'Emma (avec des tirets) ne respectent pas le format demandé.

  • ✅ Correction
    $ sed -E 's/( [0-9]{2}){2};/ XX XX;/' contacts.txt
    Alice Martin;alice.martin@exemple.fr;06 12 34 XX XX;Paris
    Bob Durand;bob@mail.com;07 98 76 XX XX;Lyon
    Chloé Petit;chloe.petit@exemple.fr;01 23 45 XX XX;Paris
    David Leroy;david.leroy(at)mail.com;0612345678;Marseille
    Emma Roux;emma.roux@exemple.org;06-11-22-33-44;Lille

    Le fichier n'est pas modifié ; ajoute -i.bak pour l'écrire réellement (avec une copie de sauvegarde).

💬 Questions fréquentes

Les questions qui reviennent le plus souvent sur ce module, avec leurs réponses.

find affiche des dizaines de « Permission non accordée »

C'est normal : en tant qu'utilisateur, tu n'as pas le droit d'entrer dans tous les dossiers. Masque ces messages avec 2>/dev/null (module 05), ou lance la recherche avec sudo si tu as vraiment besoin de tout parcourir.

Ma regex fonctionne sur un site de test, mais pas avec grep

Trois causes fréquentes : il manque -E (sans lui, +, ?, {} et | sont des caractères ordinaires) ; le motif n'est pas entre apostrophes ; ou il utilise une syntaxe d'un autre langage, comme \d pour un chiffre. grep ne la connaît pas : écris [0-9] ou [[:digit:]] (ou utilise grep -P, compatible Perl).

Quelle différence entre -exec … \; et -exec … + ?

Avec \;, la commande est lancée une fois par fichier (1 000 fichiers = 1 000 lancements). Avec +, les fichiers sont regroupés et la commande est lancée le moins de fois possible : bien plus rapide. Utilise \; seulement si la commande n'accepte qu'un fichier à la fois.