DevGuide

Antiseche de la commande find : les recettes utiles

Sur cette page
  1. Trouver un fichier par nom
  2. Fichiers seuls, dossiers seuls
  3. Trouver les gros fichiers (et les petits)
  4. Trouver les fichiers modifiés récemment
  5. Trouver et supprimer
  6. Exécuter une commande sur chaque résultat : -exec et xargs
  7. Combiner, nier, élaguer
  8. Et après

Vous arrivez d'une barre de recherche avec une commande find a moitie formee dans la tete. Du genre trouver un fichier qui s'appelle, euh. D'accord. On ne va pas vous infliger un cours d'histoire sur find et ses origines dans les annees soixante-dix. Les recettes que vous tapez vraiment sont juste en dessous, les plus demandees en premier, pour que vous puissiez copier, changer le chemin, et retourner regler ce qui a casse. Un truc a savoir avant de scroller : find se lit de gauche a droite, et ce qui suit le chemin, ce sont des tests et des actions, pas des options au sens habituel. C'est pour ca que l'ordre compte et qu'un espace en trop peut tout faire planter.

The short answer

Les recettes que vous tapez vraiment, vite : find . -name "*.log" par nom (motif entre guillemets, -iname quand la casse est incertaine), find . -type f -size +100M pour les gloutons du disque, find . -mtime -7 pour la derniere semaine, find . -name "*.tmp" -delete pour nettoyer (lancez-la une fois sans -delete d'abord), et -exec cmd {} + pour lancer une commande sur chaque resultat.

7 objectifsnom, type, taille, temps...
-exec {} +bat xargs par reflexe
-deletelistez avant, toujours
Fiche reponse : trouver par nom avec -name, par type avec -type f, par taille avec -size +100M, par temps avec -mtime -7, supprimer avec -delete, et lancer une commande avec -exec {} plus.
Chaque recette que vous tapez, regroupee selon ce que vous cherchez vraiment a faire. PNG

Vous arrivez d'une barre de recherche avec une commande à moitié formée dans la tête. Du genre « trouver un fichier qui s'appelle, euh ». D'accord. On ne va pas vous infliger un cours d'histoire sur find et ses origines dans les années soixante-dix. Les recettes que vous tapez vraiment sont juste en dessous, les plus demandées en premier, pour que vous puissiez copier, changer le chemin, et retourner régler ce qui a cassé.

Un truc à savoir avant de scroller. find se lit de gauche à droite, et ce qui suit le chemin, ce sont des tests et des actions, pas des options au sens habituel. C'est pour ça que l'ordre compte et qu'un espace en trop peut tout faire planter. Vous allez voir.

Trouver un fichier par nom

Celle que tout le monde cherche sur Google. Le . du début, c'est le dossier où chercher, autrement dit « ici et tout ce qu'il y a en dessous ». Mettez le motif entre guillemets, sinon le shell développe * dans votre dossier courant avant même que find le voie, et vous récoltez une erreur incompréhensible.

RecetteCe qu'elle fait
find . -name "*.log"Tous les fichiers .log sous le dossier courant, sensible à la casse
find . -iname "readme*"Pareil mais insensible à la casse, donc README, readme, ReadMe correspondent tous
find /etc -name "*.conf"Chercher dans un chemin précis plutôt qu'ici
find . -name "*.log" -o -name "*.txt"Les logs ou les fichiers texte (on revient sur -o plus bas)

Si vous préférez cliquer pour obtenir la ligne exacte plutôt que mémoriser les règles de guillemets, notre générateur de commande find la construit pour vous. Aucune honte à ça. Je le garde ouvert dans un onglet plus souvent que je ne l'avouerais.

Fichiers seuls, dossiers seuls

-type f limite aux fichiers ordinaires. -type d limite aux dossiers. Vous allez combiner ça avec presque tout le reste, parce que « trouve-moi un fichier » et « trouve-moi un dossier », ce sont deux boulots différents, et les mélanger, c'est comme ça qu'on supprime un répertoire par accident.

RecetteCe qu'elle fait
find . -type f -name "*.bak"Seulement les fichiers en .bak, jamais les dossiers
find . -type d -name "cache"Seulement les dossiers nommés cache
find . -type f -emptyLes fichiers vides (zéro octet)
find . -type d -emptyLes dossiers vides, le genre qui s'accumule après une suppression bâclée

Trouver les gros fichiers (et les petits)

Le disque est plein, il vous faut les coupables. -size +100M se lit « plus gros que 100 mégaoctets ». Le signe, c'est toute l'astuce : + veut dire plus que, - veut dire moins que, et sans signe ça veut dire exactement cette taille, ce qui n'est presque jamais ce que vous voulez. Les suffixes sont k, M, G pour kilo, méga, giga.

RecetteCe qu'elle fait
find . -type f -size +100MFichiers plus gros que 100 Mo. La chasse classique aux gloutons du disque
find . -type f -size -1kFichiers plus petits que 1 Ko
find . -type f -size +1GLes trucs vraiment énormes, au-delà du gigaoctet

Franchement, associez ça à -exec du -h {} + quand vous voulez aussi afficher les tailles. find tout seul ne liste que des chemins, ce qui vous dit ce qui est gros par catégorie mais pas de combien.

Trouver les fichiers modifiés récemment

Deux horloges ici, et les gens les confondent sans arrêt. -mtime compte en jours, -mmin compte en minutes. Le signe change le sens comme vous l'espérez : -mtime -7 c'est « modifié dans les 7 derniers jours », -mtime +30 c'est « plus vieux que 30 jours ». Ce signe moins piège tout le monde les dix premières fois, moi compris.

RecetteCe qu'elle fait
find . -mtime -7Modifié dans les 7 derniers jours
find . -mtime +30Plus vieux que 30 jours, parfait pour les nettoyages
find . -mmin -60Touché dans la dernière heure, mon réflexe pour « qu'est-ce que ce script vient d'écrire ? »
find . -type f -mtime -1 -name "*.log"Les fichiers log modifiés dans le dernier jour

Trouver et supprimer

La dangereuse. -delete efface tout ce qui a correspondu, sans confirmation, sans retour en arrière. Donc la règle, et je mourrai sur cette colline : lancez d'abord la commande sans aucun -delete, regardez la liste de près, ensuite ajoutez-le. Deux secondes de prudence valent mieux qu'une restauration dont vous n'avez pas la sauvegarde.

RecetteCe qu'elle fait
find . -name "*.tmp"Étape un : juste lister ce qui partirait
find . -name "*.tmp" -deleteÉtape deux : supprimer pour de vrai les fichiers .tmp
find . -type d -empty -deleteVider les dossiers vides

Un piège : -delete implique un parcours en profondeur d'abord, donc il efface le contenu avant le dossier qui le contient. C'est en général ce que vous voulez. Si un dossier n'est pas vide par contre, il ne le supprime pas, et vous verrez râler un « Directory not empty ».

Exécuter une commande sur chaque résultat : -exec et xargs

C'est là que find passe de « lister des trucs » à « faire des trucs ». Le {} est un emplacement réservé pour chaque chemin trouvé. Et il y a deux fins, qui se ressemblent presque et se comportent très différemment.

RecetteCe qu'elle fait
find . -name "*.sh" -exec chmod +x {} \;Lance chmod une fois par fichier. Le \; termine la commande
find . -name "*.log" -exec gzip {} +Regroupe les fichiers en un (ou quelques) appel(s) à gzip. Bien plus rapide
find . -name "*.jpg" -print0 | xargs -0 ls -lPasse à xargs, séparé par des zéros pour que les espaces dans les noms survivent

La différence entre \; et + est réelle, pas du pinaillage. Avec \;, find lance votre commande une fois pour chaque fichier. Mille résultats, mille processus. Avec +, il entasse autant de chemins que possible sur une seule ligne de commande et la lance une poignée de fois. Sur une grosse arborescence, c'est l'écart entre « instantané » et « va te faire un café ».

Terminal montrant les recettes find les plus utilisees : trouver par nom, trouver les fichiers de plus de 100M, trouver les modifies des 7 derniers jours, supprimer les fichiers tmp, et gziper chaque resultat avec -exec {} plus.
Les recettes les plus demandees, en premier. Copiez, changez le chemin, et c'est fait. PNG

Mon avis : utilisez -exec + et arrêtez de dégainer xargs par réflexe. Pour la plupart des « fais X sur chaque fichier », -exec cmd {} + est plus rapide que -exec cmd {} \; et plus sûr qu'un | xargs naïf, parce qu'il gère les noms avec espaces, guillemets et sauts de ligne sans que vous ayez à penser à -print0. xargs garde son utilité pour le parallélisme (xargs -P) ou pour nourrir des outils qui s'entendent mal avec -exec. Mais ce que les gens oublient vraiment ? Le \; à la fin. Omettez-le et find sort juste une erreur « missing argument to -exec », à chaque fois, et vous allez la fixer une minute en vous demandant pourquoi.

Combiner, nier, élaguer

Les tests s'empilent en ET par défaut, juste en se côtoyant. Pour le OU vous l'écrivez avec -o. Pour « tout sauf », vous niez avec !. Et quand un dossier géant comme node_modules vous fait perdre votre temps, vous l'élaguez pour que find n'y descende même pas.

RecetteCe qu'elle fait
find . -type f -name "*.js" -size +1MFichiers JS et plus gros qu'1 Mo (le ET est implicite)
find . -name "*.jpg" -o -name "*.png"jpg ou png
find . -type f ! -name "*.md"Tous les fichiers sauf le Markdown (notez le !)
find . -path "*/node_modules/*" -prune -o -name "*.js" -printIgnore node_modules entièrement, puis affiche les .js
find . -maxdepth 1 -type fLes fichiers du dossier courant seulement, sans récursion
find . -user deploy -type fLes fichiers appartenant à l'utilisateur deploy
find . -type f -perm 644Les fichiers avec le mode de permission 644

Cette ligne d'élagage a l'air cryptique, je sais. Lisez-la comme une phrase : « si le chemin est dans node_modules, élague (n'y descends pas), sinon affiche les .js qui correspondent ». Le -print à la fin compte ici, parce qu'une fois que vous avez utilisé -prune le comportement d'affichage par défaut change, et l'omettre est un grand classique du « pourquoi ça marche pas ».

-maxdepth est le sous-estimé. Mettez-le tôt et find arrête de creuser dans les arborescences profondes, ce qui sur un montage réseau ou un projet node peut transformer un parcours de 30 secondes en clignement d'œil. Côté permissions, si vous préférez raisonner sur 644 contre 755 visuellement, notre calculateur de permissions chmod détaille exactement ce que chaque mode octal accorde.

Et après

Voilà la trousse de travail. Nom, type, taille, temps, suppression, exec, et la logique de combinaison et d'élagage qui relie le tout. Quatre-vingt-dix pour cent de mon usage réel de find, c'est un mélange de ça, et les dix pour cent restants je les recherche comme tout le monde.

Si votre journée déborde des simples fichiers, le même réflexe se transpose. Vous tripotez des connexions et des interfaces ? Voyez nos commandes réseau Linux avec ip et ss. Vous sautez d'une distribution à l'autre en oubliant si c'est apt ou dnf cette semaine ? La référence des commandes par distribution aligne les gestionnaires de paquets côte à côte. Des outils différents, le même instinct : arrêtez de mémoriser, gardez une bonne antisèche à portée.

Questions fréquentes

Comment trouver un fichier par nom sous Linux ?

Utilisez find avec -name et un motif entre guillemets : find . -name "*.log" cherche dans le dossier courant et tout ce qu il y a en dessous les fichiers en .log. Mettez le motif entre guillemets pour que le shell ne developpe pas le joker avant que find tourne. Si la casse peut varier, utilisez plutot -iname, qui fait correspondre README, readme et ReadMe pareil.

Comment trouver les gros fichiers qui remplissent le disque ?

Lancez find . -type f -size +100M pour lister tous les fichiers plus gros que 100 megaoctets sous le dossier courant. Le signe plus veut dire plus gros que, un moins voudrait dire plus petit que, et les suffixes sont k, M et G. Ajoutez -exec du -h {} + a la fin si vous voulez aussi voir les tailles affichees a cote de chaque chemin au lieu des seuls noms.

Quelle difference entre -exec {} \; et -exec {} + ?

Les deux lancent une commande sur les fichiers trouves par find. Avec \; find lance la commande une fois par fichier, donc mille resultats font mille processus. Avec + il regroupe plusieurs chemins en une seule commande, lancee seulement quelques fois, ce qui est bien plus rapide sur les grosses arborescences. Utilisez + quand la commande accepte plusieurs arguments, et n oubliez pas que la commande a quand meme besoin de son terminateur.

Comment trouver et supprimer des fichiers avec find ?

Ajoutez -delete, comme dans find . -name "*.tmp" -delete. Il n y a ni confirmation ni retour en arriere, donc lancez d abord la meme commande sans -delete pour voir exactement ce qui partirait, puis ajoutez-le une fois que vous faites confiance a la liste. Pour les dossiers vides, find . -type d -empty -delete les vide proprement.

Comment exclure un dossier comme node_modules de find ?

Utilisez -prune pour que find n y descende jamais : find . -path "*/node_modules/*" -prune -o -name "*.js" -print. Lisez-le comme si le chemin est dans node_modules, ignore-le, sinon affiche les .js qui correspondent. Le -print a la fin est obligatoire ici, parce qu utiliser -prune change le comportement d affichage par defaut. Pour une recherche rapide sur un seul niveau a la place, -maxdepth 1 coupe entierement la recursion.