Linux sans magie #28 — find : rechercher des fichiers par nom, type, taille et date
Comprendre find sous Linux pour rechercher des fichiers par nom, type, taille et ancienneté, combiner des critères et vérifier les résultats avant toute action.
Après avoir travaillé sur les flux texte avec grep, sed et awk, nous revenons au système de fichiers avec une commande essentielle : find.
find parcourt une arborescence à partir d’un ou plusieurs points de départ et évalue une expression pour chaque entrée rencontrée.
Cette logique permet de répondre à des besoins très courants :
- retrouver des fichiers dont le nom suit un motif ;
- distinguer fichiers et répertoires ;
- rechercher par taille ;
- rechercher selon l’ancienneté ;
- combiner plusieurs critères ;
- vérifier précisément une sélection avant d’exécuter une action.
L’objectif de cet article est de maîtriser la recherche. Les actions plus avancées avec -exec, xargs ou la suppression feront l’objet d’étapes séparées.
Le modèle mental de find
La forme générale est :
find POINT_DE_DEPART EXPRESSION
Exemple :
find /tmp
Sans critère supplémentaire, find affiche les entrées rencontrées sous le point de départ.
Le point de départ peut être :
. → répertoire courant
/tmp → répertoire /tmp
/var/log → répertoire /var/log
/home/user → un répertoire précis
Pour une recherche dans le répertoire courant :
find .
Le . signifie simplement : « commencer ici ».
Préparer un lab reproductible
Créons une petite arborescence dédiée :
mkdir -p /tmp/linux-sans-magie-28/{logs,configs,archives}
printf 'web\n' > /tmp/linux-sans-magie-28/configs/web.conf
printf 'db\n' > /tmp/linux-sans-magie-28/configs/db.conf
printf 'old log\n' > /tmp/linux-sans-magie-28/logs/app-old.log
printf 'new log\n' > /tmp/linux-sans-magie-28/logs/app.log
truncate -s 2K /tmp/linux-sans-magie-28/archives/small.bin
truncate -s 2M /tmp/linux-sans-magie-28/archives/large.bin
cd /tmp/linux-sans-magie-28
Toutes les recherches de l’article resteront dans ce répertoire.
Rechercher par nom avec -name
Pour retrouver les fichiers dont le nom se termine par .conf :
find . -name '*.conf'
Résultat attendu :
./configs/web.conf
./configs/db.conf
Les guillemets sont importants.
Sans eux, le shell pourrait développer *.conf avant que find ne reçoive le motif.
La forme sûre est donc :
find . -name '*.conf'
et non :
find . -name *.conf
Rechercher sans tenir compte de la casse
GNU find propose -iname pour une comparaison de nom insensible à la casse.
Exemple :
touch configs/API.CONF
find . -iname '*.conf'
Le résultat inclut aussi :
./configs/API.CONF
Pour des scripts destinés à plusieurs environnements Unix, il faut cependant vérifier la disponibilité des options non POSIX dans l’implémentation cible.
Distinguer fichiers et répertoires avec -type
Le test -type permet de filtrer selon le type d’entrée.
Pour afficher uniquement les fichiers ordinaires :
find . -type f
Pour afficher uniquement les répertoires :
find . -type d
On peut combiner -type et -name :
find . -type f -name '*.log'
Résultat :
./logs/app-old.log
./logs/app.log
Dans cette expression, les critères sont combinés implicitement avec un ET logique.
Autrement dit :
-type f ET -name '*.log'
Rechercher par taille avec -size
Le test -size permet de sélectionner selon la taille.
Avec GNU find, le suffixe k correspond à des unités de 1024 octets et M à des unités de 1024 × 1024 octets.
Pour rechercher les fichiers dont la taille, exprimée dans l’unité choisie après arrondi, dépasse une unité de 1 MiB :
find . -type f -size +1M
Dans notre lab, le fichier large.bin doit apparaître.
Pour chercher les fichiers dont la taille correspond à moins de dix unités de 1 KiB après l’arrondi appliqué par find :
find . -type f -size -10k
Avec GNU find, la taille est exprimée dans l’unité choisie et arrondie vers le haut avant l’évaluation du test. Les préfixes signifient alors :
+n → plus de n unités
-n → moins de n unités
n → exactement n unités
Il ne faut donc pas raisonner uniquement comme sur une comparaison brute en octets lorsque l’on utilise k, M ou G. L’unité et l’arrondi font partie de la sémantique du test.
Rechercher selon l’ancienneté avec -mtime
Le test -mtime s’appuie sur l’âge de la date de modification, exprimé en périodes de 24 heures complètes dans GNU find.
La forme :
find . -type f -mtime +7
sélectionne les fichiers dont le temps de modification correspond à plus de sept périodes de 24 heures selon les règles d’arrondi de find.
Pour le lab, nous pouvons créer un fichier artificiellement ancien :
touch -d '10 days ago' logs/app-old.log
Puis :
find . -type f -mtime +7
Résultat attendu :
./logs/app-old.log
Il faut éviter de lire -mtime +7 comme une simple comparaison à la seconde près.
Pour des besoins temporels précis, la documentation GNU décrit aussi d’autres tests et options plus adaptés.
Comprendre +n, -n et n
La même convention apparaît dans plusieurs tests numériques.
Avec -mtime :
-mtime +7 → valeur supérieure à 7 selon l’unité du test
-mtime -7 → valeur inférieure à 7
-mtime 7 → valeur égale à 7 après le calcul/arrondi du test
Avec -size, le principe de signe reste similaire, même si l’unité dépend du suffixe choisi.
Cette syntaxe mérite d’être comprise avant d’utiliser find dans des tâches de nettoyage automatiques.
Combiner plusieurs critères
Pour rechercher des fichiers .log anciens :
find . -type f -name '*.log' -mtime +7
On peut lire cette expression comme :
fichier ordinaire
ET
nom se terminant par .log
ET
ancien selon -mtime +7
Le résultat attendu dans notre lab est :
./logs/app-old.log
Cette façon de construire progressivement l’expression est préférable à une commande complexe écrite d’un seul coup.
Utiliser OR avec -o
Pour rechercher des fichiers .conf ou .log :
find . -type f \( -name '*.conf' -o -name '*.log' \)
Les parenthèses sont échappées pour qu’elles soient transmises à find au lieu d’être interprétées par le shell.
Cette expression signifie :
-type f
ET
(
-name '*.conf'
OU
-name '*.log'
)
Les parenthèses sont importantes, car les opérateurs de find ont des règles de priorité.
Pour éviter les surprises, rendez les groupements explicites dès qu’un -o apparaît.
Exclure avec !
On peut inverser un test avec !.
Exemple :
find . -type f ! -name '*.log'
Cette commande affiche les fichiers ordinaires dont le nom ne se termine pas par .log.
L’opérateur ! doit être lu comme une négation du test qui suit.
Limiter la profondeur avec GNU find
GNU find propose -maxdepth.
Pour ne regarder que le point de départ et son premier niveau :
find . -maxdepth 1
Cette option est pratique lorsqu’on ne veut pas parcourir toute une arborescence.
Elle n’est pas portable vers toutes les implémentations historiques de find, donc un script multi-plateforme doit vérifier cette dépendance.
Vérifier la sélection avant toute action
La règle opérationnelle la plus importante avec find est simple :
séparer d’abord la recherche de l’action.
Avant toute commande qui copie, déplace ou supprime des fichiers, commencez par afficher la sélection.
Exemple :
find . -type f -name '*.log' -mtime +7
Vérifiez chaque chemin.
Affinez éventuellement l’expression.
Puis seulement, dans une étape séparée, associez une action appropriée.
Cette discipline est particulièrement importante pour les critères temporels ou les expressions combinant -o, ! et plusieurs parenthèses.
Pourquoi nous n’utilisons pas encore -delete
GNU find dispose d’une action -delete.
Elle est puissante, mais destructive.
Dans cet article consacré à la sélection, l’utiliser n’apporterait rien à l’objectif pédagogique et augmenterait inutilement le risque.
Nous restons donc sur l’action d’affichage implicite.
Une règle saine consiste à produire d’abord une liste de chemins vérifiée avant d’envisager une suppression.
Premier diagnostic en cas de résultat inattendu
Si une commande find ne retourne pas ce que vous attendez, vérifiez les éléments séparément.
Commencez par le point de départ :
find .
Puis le type :
find . -type f
Puis le nom :
find . -type f -name '*.log'
Enfin, ajoutez le critère supplémentaire :
find . -type f -name '*.log' -mtime +7
Cette méthode réduit le nombre de variables à diagnostiquer à chaque étape.
Bonnes pratiques
Citez les motifs de nom pour empêcher leur expansion prématurée par le shell :
find . -name '*.conf'
Ajoutez -type f lorsque vous cherchez réellement des fichiers et non des répertoires portant un nom similaire.
Construisez les expressions progressivement.
Utilisez des parenthèses explicites avec -o.
Vérifiez le sens des tests temporels et des unités de taille avant toute automatisation.
Ne transformez jamais une commande de recherche en commande destructive sans avoir contrôlé auparavant la liste des chemins sélectionnés.
Sécurité
find lui-même peut rester purement descriptif lorsqu’il se contente d’afficher des chemins.
Le risque apparaît lorsqu’on lui associe une action externe, une suppression ou un traitement automatisé.
Les arborescences contenant des noms de fichiers inattendus exigent aussi une attention particulière : espaces, tabulations et retours à la ligne peuvent rendre dangereuse une transmission naïve vers une autre commande.
Ce problème sera précisément traité dans le #29 avec -print0 et xargs -0.
Coûts
Les recherches présentées sont locales et n’introduisent pas de coût de service cloud.
Elles peuvent cependant consommer des ressources CPU et surtout des entrées/sorties disque lorsqu’elles parcourent de très grandes arborescences.
Limites et points de vigilance
Cet article ne couvre pas encore :
-execet-execdir;-print0;xargs;-deleteen pratique ;-prune;- les permissions et erreurs d’accès ;
- les systèmes de fichiers distants ou montages particuliers ;
- les tests temporels plus fins comme
-mmin; - les prédicats avancés.
Le but est d’abord de savoir construire une sélection fiable.
Rollback ou nettoyage
Les commandes de recherche sont non destructives.
Le lab a toutefois créé des fichiers temporaires.
Pour supprimer uniquement l’environnement du lab :
rm -rf /tmp/linux-sans-magie-28
Cette commande cible explicitement le répertoire temporaire créé au début de l’article.
Références officielles
- GNU Findutils Manual — GNU Project
- GNU Findutils Manual — Name — GNU Project
- GNU Findutils Manual — Size — GNU Project
- GNU Findutils Manual — Age Ranges — GNU Project
- GNU Findutils Manual — Combining Primaries With Operators — GNU Project
Conclusion
find devient beaucoup plus simple lorsqu’on sépare trois éléments :
où chercher → point de départ
quoi tester → -name, -type, -size, -mtime...
comment combiner → ET implicite, -o, !, parenthèses
La compétence essentielle n’est pas de mémoriser beaucoup d’options.
Elle consiste à construire une sélection progressive, lisible et vérifiable avant d’associer la moindre action aux fichiers trouvés.
