🎯 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
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ère | Trouve | Exemple |
|---|---|---|
-name / -iname | Par nom (jokers permis), -iname ignore la casse | -name "*.log" |
-type f / d / l | Fichiers / dossiers / liens symboliques | -type d |
-size | Par taille : + plus de, - moins de (k, M, G) | -size +100M |
-mtime / -mmin | Modifiés il y a moins (-) ou plus (+) de N jours / minutes | -mtime -7 |
-user / -group | Par propriétaire / groupe | -user www-data |
-perm | Par droits | -perm -4000 (bit SUID) |
-empty | Fichiers ou dossiers vides | -type d -empty |
-maxdepth N | Ne 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
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
| Action | Effet |
|---|---|
-print | Affiche le chemin (action par défaut) |
-ls | Affiche 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 |
-delete | Supprime 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
-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
| Commande | Répond à | Exemple |
|---|---|---|
which | Quel programme sera lancé si je tape ce nom ? | which python3 → /usr/bin/python3 |
type -a | Est-ce un alias, une primitive, un programme ? Tous les emplacements | type -a ls |
whereis | Où sont le programme, ses sources et sa page de manuel ? | whereis bash |
command -v | Comme which, en version portable pour les scripts | command -v git || echo "absent" |
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
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
| Symbole | Signifie | Exemple | Correspond à |
|---|---|---|---|
^ | Début de ligne | ^root | « root » en tout début de ligne |
$ | Fin de ligne | bash$ | lignes qui finissent par « bash » |
. | N'importe quel caractère (un seul) | c.t | cat, cot, c-t, c4t… |
* | L'élément précédent, 0 fois ou plus | ab*c | ac, abc, abbbc… |
[abc] | Un caractère de la liste | [Ll]inux | Linux, 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
| Symbole | Signifie | Exemple |
|---|---|---|
+ | 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|b | a OU b | error|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.
Les deux utilisent *, ? et [ ], mais pas avec le même sens :
Joker du shell (ls *.txt) | Regex (grep) | |
|---|---|---|
* | n'importe quelle suite de caractères | l'élément précédent, répété |
? | un caractère | l'élément précédent, facultatif (en -E) |
. | un vrai point | n'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
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 ?
~/labo ?-type d, on obtiendrait aussi les fichiers vides."*.conf" entre guillemets dans find -name ?*.conf dans le dossier courant.locate ne trouve pas un fichier créé il y a une minute. Pourquoi ?sudo updatedb met la base à jour immédiatement.^[0-9] ?^ ancre au début de ligne (attention : à l'intérieur des crochets, [^0-9] signifie « pas un chiffre »).. = un caractère quelconque, * = répété. Le * seul est le joker du shell.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.-o de grep ?-v qui inverse. -o sert à extraire.find … -print0 | xargs -0 plutôt que find … | xargs ?🚀 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 1doit ê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/nullTu 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
whichne voit pas l'alias ;type -amontre tout, y compris/bin/lsqui 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.bakpour 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.