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 :

  • -exec et -execdir ;
  • -print0 ;
  • xargs ;
  • -delete en 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

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.