Comment j'ai finalement déverrouillé la commande find de Linux
J'utilise la commande find depuis des décennies, mais je ne l'ai jamais vraiment comprise, jusqu'à maintenant. Me forcer à suivre et enfin à déchiffrer cette commande insaisissable était la clé du succès.
Sommaire
Présentation de la commande find
La commande find est l'un des programmes Linux les plus étranges que vous utiliserez. C'est suffisamment essentiel pour être omniprésent, mais suffisamment obscur pour n'être le préféré de personne. Des alternatives comme fd existent, mais find est le plus petit dénominateur commun qui fonctionne à peu près.
Dans le cas le plus simple, utiliser find est un jeu d’enfant :
find . -name '*.txt'
Ce type de requête courant recherche tous les fichiers du répertoire actuel ou de tout répertoire situé en dessous qui se terminent par « .txt ». Si vous n’en êtes jamais allé aussi loin, vous ne réalisez probablement pas à quel point la recherche est complexe. Sa page de manuel contient 1 639 lignes (version 4.9.0), et une fois que vous avez fouillé dans find, elle commence à ressembler moins à un utilitaire utile qu'à un langage de programmation à part entière.
Cette complexité m'a toujours rebuté dans le passé. J'ai longtemps voulu trouver un moyen simple de retrouver les fichiers que j'ai modifiés récemment, mais cela m'a toujours échappé. Les résultats finissent par être en proie à des fichiers .git ou à un désordre non trié. J'ai donc décidé de m'asseoir et de me familiariser enfin avec find ; le résultat était rafraîchissant.
L'utilisation de base de find ressemble à ceci :
find (starting-point...) (expression)
Find suit ensuite ces étapes pour effectuer son travail :
-
Traitez chaque fichier et répertoire dans le point de départ ; plusieurs points de départ sont pris en charge.
-
Appliquer des tests ; si le fichier les réussit tous, agissez.
-
Agir : l'action par défaut est -imprimerqui imprime le nom complet du fichier.
Un simple nu trouversans argument, répertorie tout ce qui se trouve sous le répertoire courant :
Cela peut être très utile seul, mais le véritable pouvoir de find vient des tests et des actions qu'il prend en charge.
Obtenir find pour signaler les fichiers récemment modifiés
Lorsque vous travaillez sur une tâche plus complexe comme celle-ci, c'est une bonne idée de planifier ce dont vous avez besoin, puis de déterminer comment y parvenir petit à petit. Pour le comportement que je recherche, je sais que j'ai besoin de :
-
Fichiers que je possède.
-
Fichiers qui ne se trouvent pas dans des répertoires cachés.
-
Résultats triés par date, avec les dates affichées.
Il est également utile d'avoir des données de test afin de pouvoir vérifier que votre commande fait exactement ce que vous voulez. Dans ce cas, j'utilise la structure de fichiers suivante :
Rechercher des fichiers appartenant à un utilisateur
La première tâche est simple, grâce à find -utilisateur test, qui ne correspond à un fichier que si l'utilisateur actuel en est propriétaire :
find . -user "${USER}"
Si vous exécutez ce qui précède, vous remarquerez peut-être que la sortie contient des répertoires :
Pour vous assurer que la liste finale ne contient que des fichiers, utilisez find -taper test. Cela prend un seul caractère pour désigner le type de fichier à rechercher : f pour un fichier normal, d pour un répertoire et l pour un lien symbolique, entre autres :
find . -user "${USER}" -type f
À ce stade, find signale tous les fichiers (et non les répertoires) appartenant à l'utilisateur actuel :
Rechercher des fichiers qui ne se trouvent pas dans des répertoires cachés
La partie suivante de la tâche consiste à arrêter de rechercher des fichiers de rapport dans des répertoires cachés. L'action -prune indique à find de ne pas descendre dans un répertoire correspondant :
find . -path "*/.*/*" -prune
Les résultats de cette commande peuvent sembler étranges au premier abord, presque à l’opposé de ce que nous souhaitons :
Cela est dû à la façon dont se comporte l'action d'élagage, alors voici ce qui se passe :
-
Le test -path fait correspondre tous les fichiers (y compris les répertoires) avec un chemin qui inclut au moins un répertoire caché.
-
L'action -prune empêche find d'entrer dans ces répertoires.
-
Puisqu'il n'y a pas d'action autre que -prune, find applique l'action -print par défaut. Cette commande est équivalente à
find . -path "*/.*/*" -prune -print.
Au lieu d'imprimer les répertoires cachés qui sont élagués, vous pouvez imprimer tout le reste en utilisant -o :
find . -path "*/.*/*" -prune -o -print
L'opérateur -o est un OU logique, ce qui signifie que find correspondra soit à l'expression précédente, soit à la suivante. Ainsi, si un chemin a un répertoire caché, il sera élagué ; sinon il sera imprimé (une expression sans test correspondra toujours).
À ce stade, vous pouvez fusionner l'expression d'origine filtrée par propriétaire et type de fichier :
find . -path "*/.*/*" -prune -o -user "${USER}" -type f -print
Cette commande find localise tous les fichiers requis, et pas plus :
Il ne reste plus qu'à les trier par dernière modification et à afficher cette date à côté de chaque fichier.
Vous pouvez utiliser le test -path pour obtenir les mêmes résultats, avec une commande légèrement plus courte :
find . -type f -not -path '*/.*/*' -user "${USER}"
Si vous essayez ceci, vous obtiendrez les mêmes résultats que la version qui utilise -prune. La différence est que -prune est plus efficace car il évite de tester des fichiers dans des répertoires cachés. Si vous travaillez avec de nombreux répertoires, vous devez toujours utiliser -prune pour ignorer ceux que vous pouvez éviter.
Triez les résultats et imprimez-les correctement
La commande find ne gère pas le tri elle-même ; pour cette tâche, vous pouvez utiliser sortl'une des commandes essentielles de traitement de texte. Cependant, vous aurez d’abord besoin de cette date de modification pour chaque fichier. L'action -printf indique find exactement comment vous souhaitez obtenir sa sortie :
find . -path "*/.*/*" -prune -o -user "${USER}" -type f -printf "%TY-%Tm-%Td %pn"
L'action -printf utilisera le contenu de la chaîne citée pour formater les informations du fichier. Dans cet exemple, %TY fait référence à l'année de la dernière heure modifiée. %Tm et %Td sont respectivement le mois et le jour, tandis que %p est le nom du fichier.
Vous pouvez spécifier une date plus granulaire pour un tri plus précis, mais je ne m'intéresse vraiment qu'aux dates, donc la dernière étape consiste à trier pour trier. Notez que je commande chaque ligne avec la date en premier. Cela a deux objectifs : cela permet de garder tout bien aligné, mais cela rend également le tri une tâche triviale. Dirigez simplement les résultats de find vers tri :
find . -path "*/.*/*" -prune -o -user "${USER}" -type f -printf "%TY-%Tm-%Td %pn" | sort
