Recherche de fichiers
locate
La commande locate est un peu la solution de facilité pour chercher des fichiers. J'exagère un peu : locate est en effet plus facile à utiliser que find, mais elle a d'autres avantages.
Principe de fonctionnement
locate utilise une base de données de fichiers créée préalablement, et cherche dans cette base un nom de fichier donné.
Avantage : la recherche est très rapide.
Inconvénients : comme il faut parcourir toute l'arborescence du système, la mise à jour de la base de donnée est longue et on ne la fait donc pas souvent. Cela implique qu'une recherche a des chances de donner des résultats faux (un fichier qui n'existe plus sur le disque mais encore présent dans la base de données), ou de ne pas donner tous les résultats (les fichiers créés depuis la dernière mise à jour ne seront pas trouvés).
Utilisation
Comme vous l'avez compris l'utilisation de locate est très simple.
Pour mettre à jour la base de données, tapez simplement (en root) :
# updatedb
Il est possible d'exécuter cette commande en simple utilisateur, mais la base construite ne comportera pas les fichiers situés dans des répertoires auxquels l'utilisateur n'a pas accès (et des messages d'erreur apparaitront pour chacun de ces répertoires).
Ne faites pas attention aux messages d'erreur « Aucun fichier ou répertoire de ce type ».
Pour rechercher un fichier, tapez :
$ locate fichier
Tous les noms de fichiers contenant fichier seront affichées.
find
La commande find recherche récursivement toutes les occurrences d'un fichier à partir d'un répertoire. En français, cela veut dire qu'on lui donne un répertoire et un nom à chercher, et qu'il va regarder dans le répertoire lui-même ainsi que tous les répertoires fils (sous-répertoires) si le fichier recherché existe. Si oui il l'affiche avec son chemin relatif. Il y a aussi d'autres possibilités, comme d'exécuter une commande sur le fichier au lieu de simplement afficher son nom.
Recherche simple par nom
Pour chercher toutes les occurrences du fichier fichier dans le répertoire répertoire, la syntaxe est la suivante :
$ find répertoire -name fichier
Il faut donc avant tout donner le répertoire dans lequel chercher, puis l'option -name sert à spécifier le fichier à rechercher. Comme d'habitude, si l'un des deux contient des espaces il faut le protéger avec des guillemets simples (') ou doubles (").
Par exemple, si j'ai une arborescence de fichiers :
répertoire1/fichier1 répertoire1/répertoire2/fichier1 répertoire1/répertoire2/fichier2 répertoire1/répertoire3/fichier1 répertoire1/répertoire4/fichier3
et que je veux chercher le fichier fichier1, je vais taper :
$ find répertoire1 -name fichier1
Il va alors m'afficher :
répertoire1/répertoire2/fichier1 répertoire1/répertoire3/fichier1 répertoire1/fichier1
A noter que si aucun nom de fichier n'est spécifié, find affichera simplement la liste de tous les fichiers de l'arborescence :
$ find répertoire1/ répertoire1/ répertoire1/répertoire2 répertoire1/répertoire2/fichier1 répertoire1/répertoire2/fichier2 répertoire1/répertoire3 répertoire1/répertoire3/fichier1 répertoire1/répertoire4 répertoire1/répertoire4/fichier3 répertoire1/fichier1
Recherche simple avec expression régulière
L'inconvénient de la première solution, c'est que le nom spécifié doit être exactement le nom du fichier recherché.
Mais que l'on se rassure, il est également possible de rechercher tous les fichiers correspondant à un certain motif : il suffit de remplacer l'option -name par -regex (pour regular expression) et le nom du fichier par une... expression régulière, tout à fait !
Cela nous donne donc :
$ find répertoire -regex 'expression'
La protection de l'expression par des guillemets simples est indispensable (pour éviter au shell d'interpréter les * par exemple).
Mais... Que mettre à la place de l'expression ? Eh bien je ne vais pas expliquer les expressions régulières ici, mais juste donner quelques exemples.
Rechercher les fichiers commençant par début :
$ find répertoire -regex 'début.*'
Rechercher les fichiers finissant par fin :
$ find répertoire -regex '.*fin'
Rechercher les fichiers contenant par mot :
$ find répertoire -regex '.*mot.*'
Bon allez, petite explication quand même : dans l'expression régulière, le point ('.') remplace n'importe quel caractère, et l'astérisque ('*') signifie que le caractère précédent est répété un nombre quelconque de fois.
La chaîne '.*' veut donc dire « autant de caractères quelconques que l'on veut », autrement dit n'importe quelle chaîne de caractères, et '.*fin' se traduit par « n'importe quelle chaîne suivie de "fin" », ou encore « une chaîne de caractères se terminant par "fin" ».
Par contre je n'ai pas trouvé comment faire une recherche insensible à la casse. Si quelqu'un a une idée...
Traitement des fichiers trouvés
Comme je l'ai dit plus haut find a l'avantage de pouvoir effectuer des traitements sur les fichiers trouvés.
Sans confirmation
L'option idoine est -exec.
La syntaxe assez peu intuitive. Derrière -exec, on met la commande à exécuter suivie de ses arguments. La chaîne {} remplace le nom du fichier courrant. Pour signifier la fin des options de la commande à exécuter, on met un point-virgule. Pour éviter que le shell n'interprète les accolades et le point-virgule, on les protège.
$ find répertoire -name fichier -exec commande -arg1 -arg2 '{}' ';'
exécute la commande commande sur chaque fichier trouvé, avec les arguments -arg1 et -arg2 de commande.
Par exemple pour rechercher et supprimer tous les fichiers finissant par le caractère '~' à partir du répertoire courrant :
$ find . -regex '.*~' -exec rm -v '{}' ';'
On utilise ici l'option -v de rm pour avoir la liste des fichiers supprimés.
Avec confirmation
Si on veut que find demande confirmation avant d'exécuter la commande, on peut utiliser -ok à la place de -exec :
$ find répertoire -name fichier -ok commande -arg1 -arg2 '{}' ';'
Pour chaque fichier trouvé, find affiche la commande qu'il va exécuter et attendra confirmation. Si on tape y (ou o dans un environnement français), la commande est exécutée ; dans les autres cas find poursuit sa recherche.
Exemple :
$ find répertoire1/ -name fichier1 -ok rm -v '{}' ';' < rm ... répertoire1/répertoire2/fichier1 > ? y détruit `répertoire1/répertoire2/fichier1' < rm ... répertoire1/répertoire3/fichier1 > ? < rm ... répertoire1/fichier1 > ?
Ici l'utilisateur a confirmé la suppression du premier fichier en tapant y, mais a simplement appuyé sur <ENTRÉE> pour les deux autres, ce qui est interprété comme un refus.
Remarque : dans ce cas précis, on peut utiliser -exec et l'option -i de rm plutôt que -ok.
Conclusion
Je me suis limité à l'utilisation de base de ces programmes (celle que j'en fais, en fait).
Pour un peu plus d'informations concernant les possibilités présentées, et pour en découvrir beaucoup d'autres, n'hésitez pas :
$ man updatedb $ man locate $ man find
Sous Debian, locate et find se trouvent dans le paquet findutils, normalement installé par défaut.