« Recherche de fichiers » : différence entre les versions

De La Mouche VII
Aller à la navigationAller à la recherche
Aucun résumé des modifications
m (Révocation des modifications de 208.109.190.98 (discussion) vers la dernière version de Xiloynaha)
 
(6 versions intermédiaires par 4 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
==locate==
[[Catégorie:Informatique]]
 
== 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.
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 ===
 
 
===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é.
'''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.
'''''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).
'''''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 ===
 
 
===Utilisation===


Comme vous l'avez compris l'utilisation de '''locate''' est très simple.
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) :
Pour mettre à jour la base de données, tapez simplement (en root) :
Ligne 29 : Ligne 22 :


Ne faites pas attention aux messages d'erreur « ''Aucun fichier ou répertoire de ce type'' ».
Ne faites pas attention aux messages d'erreur « ''Aucun fichier ou répertoire de ce type'' ».


Pour rechercher un fichier, tapez :
Pour rechercher un fichier, tapez :
  $ locate fichier
  $ locate fichier
Tous les noms de fichiers contenant ''fichier'' seront affichées.
Tous les noms de fichiers contenant ''fichier'' seront affichées.


== find ==
== 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.
La commande '''find''' recherche récursivement toutes les occurrences d'un fichier (quel que soit son type) à 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===
=== Recherche simple par motif : ''-name'' et ''-iname'' ===


Pour chercher toutes les occurrences du fichier ''fichier'' dans le répertoire ''répertoire'', la syntaxe est la suivante :
Pour chercher toutes les occurrences du fichier ''fichier'' dans le répertoire ''répertoire'', la syntaxe est la suivante :
  $ find répertoire -name fichier
  $ 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 (").
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 ("). Si l'on veut rechercher sans tenir compte de la casse, on utilise l'option '''-iname''' :
 
$ find répertoire -iname fichier
À la place du nom, on peut aussi spécifier un motif ; pour rechercher tous les fichiers d'en-tête C dans le répertoire ''répertoire'' on peut écrire :
$ find répertoire -name '*.h'


Par exemple, si j'ai une arborescence de fichiers :
Par exemple, si j'ai une arborescence de fichiers :
  répertoire1/fichier1
  répertoire1/fichier1
  répertoire1/répertoire2/fichier1
  répertoire1/répertoire2/fichier1
répertoire1/répertoire2/Fichier1
  répertoire1/répertoire2/fichier2
  répertoire1/répertoire2/fichier2
  répertoire1/répertoire3/fichier1
  répertoire1/répertoire3/fichier1
répertoire1/répertoire3/FICHIER1
  répertoire1/répertoire4/fichier3
  répertoire1/répertoire4/fichier3
et que je veux chercher le fichier ''fichier1'', je vais taper :
et que je veux chercher le fichier ''fichier1'', je vais taper :
Ligne 67 : Ligne 55 :
  répertoire1/fichier1
  répertoire1/fichier1


Si je veux effectuer la même recherche, mais sans tenir compte de la casse, je tape :
$ find répertoire1 -iname fichier1
Et j'obtiens :
répertoire1/répertoire2/fichier1
répertoire1/répertoire2/Fichier1
répertoire1/répertoire3/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 :
Si je veux chercher tous les fichiers dont le nom finit par le chiffre 3, je tape :
$ find répertoire1 -name '*3'
Et j'obtiens :
répertoire1/répertoire3
répertoire1/répertoire4/fichier3
 
À 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/
  $ find répertoire1/
  répertoire1/
  répertoire1/
  répertoire1/répertoire2
  répertoire1/répertoire2
  répertoire1/répertoire2/fichier1
  répertoire1/répertoire2/fichier1
répertoire1/répertoire2/Fichier1
  répertoire1/répertoire2/fichier2
  répertoire1/répertoire2/fichier2
  répertoire1/répertoire3
  répertoire1/répertoire3
  répertoire1/répertoire3/fichier1
  répertoire1/répertoire3/fichier1
répertoire1/répertoire3/FICHIER1
  répertoire1/répertoire4
  répertoire1/répertoire4
  répertoire1/répertoire4/fichier3
  répertoire1/répertoire4/fichier3
  répertoire1/fichier1
  répertoire1/fichier1


=== Recherche simple avec expression rationnelle : ''-regex'' et ''-iregex'' ===


Les options '''-name''' et '''-iname''' suffisent dans la plupart des cas, mais peuvent être limites si le motif à rechercher est très complexe.


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'') '''-iname''' par '''-iregex''' et le nom du fichier par une… expression rationnelle, tout à fait !


===Recherche simple avec expression régulière===
'''''Avertissement :''' dans le traitement de l'expression rationnelle, ce qui est pris en compte est l'ensemble de la ligne de sortie potentielle, et pas le nom du fichier. Par exemple si je cherche à partir du répertoire courant (<tt>find . -regex mon_expression</tt>), chaque ligne commencera par « <tt>./</tt> », et il faudra en tenir compte dans l'écriture de l'expression.''
 
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 :
Cela nous donne donc :
Ligne 94 : Ligne 96 :
La protection de l'expression par des guillemets simples est indispensable (pour éviter au shell d'interpréter les * par exemple).
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.
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'' :
Rechercher les fichiers commençant par ''début'' :
Ligne 104 : Ligne 104 :
  $ find répertoire -regex '.*fin'
  $ find répertoire -regex '.*fin'


Rechercher les fichiers contenant par ''mot'' :
Rechercher les fichiers contenant ''mot'' :
  $ find répertoire -regex '.*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.
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.
Ligne 112 : Ligne 111 :
La chaîne '''<nowiki>'.*'</nowiki>''' veut donc dire « autant de caractères quelconques que l'on veut », autrement dit n'importe quelle chaîne de caractères, et '''<nowiki>'.*fin'</nowiki>''' se traduit par « n'importe quelle chaîne suivie de "fin" », ou encore « une chaîne de caractères se terminant par "fin" ».
La chaîne '''<nowiki>'.*'</nowiki>''' veut donc dire « autant de caractères quelconques que l'on veut », autrement dit n'importe quelle chaîne de caractères, et '''<nowiki>'.*fin'</nowiki>''' se traduit par « n'importe quelle chaîne suivie de "fin" », ou encore « une chaîne de caractères se terminant par "fin" ».


 
=== Traitement des fichiers trouvés ===
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.
Comme je l'ai dit plus haut '''find''' a l'avantage de pouvoir effectuer des traitements sur les fichiers trouvés.


 
==== Sans confirmation ====
====Sans confirmation====


L'option idoine est '''-exec'''.
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.
La syntaxe est 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 '{}' ';'
  $ 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'''.
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 courant :
Par exemple pour rechercher et supprimer tous les fichiers finissant par le caractère '~' à partir du répertoire courrant :
  $ find . -regex '.*~' -exec rm -v '{}' ';'
  $ find . -regex '.*~' -exec rm -v '{}' ';'
On utilise ici l'option '''-v''' de '''rm''' pour avoir la liste des fichiers supprimés.
On utilise ici l'option '''-v''' de '''rm''' pour avoir la liste des fichiers supprimés.


==== Avec confirmation ====
==== Avec confirmation ====
Ligne 142 : Ligne 132 :
  $ find répertoire -name fichier -ok commande -arg1 -arg2 '{}' ';'
  $ 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.
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 :
Exemple :
  $ find répertoire1/ -name fichier1 -ok rm -v '{}' ';'
  $ find répertoire1/ -name fichier1 -ok rm -v '{}' ';'
  < rm ... répertoire1/répertoire2/fichier1 > ? y
  < rm répertoire1/répertoire2/fichier1 > ? y
  détruit `répertoire1/répertoire2/fichier1'
  détruit `répertoire1/répertoire2/fichier1'
  < rm ... répertoire1/répertoire3/fichier1 > ?   
  < rm ... répertoire1/répertoire3/fichier1 > ?   
Ligne 154 : Ligne 143 :
Remarque : dans ce cas précis, on peut utiliser '''-exec''' et l'option '''-i''' de '''rm''' plutôt que '''-ok'''.
Remarque : dans ce cas précis, on peut utiliser '''-exec''' et l'option '''-i''' de '''rm''' plutôt que '''-ok'''.


 
== Conclusion ==
 
 
 
 
==Conclusion==


Je me suis limité à l'utilisation de base de ces programmes (celle que j'en fais, en fait).
Je me suis limité à l'utilisation de base de ces programmes (celle que j'en fais, en fait).
Ligne 168 : Ligne 152 :
  $ man find
  $ man find


 
Sous Debian, '''locate''' et '''find''' se trouvaient traditionnellement dans le paquet '''findutils''', normalement installé par défaut. Dans les versions récentes, '''locate''' est dans un paquet séparé, et '''mlocate''', une version améliorée, est proposé par défaut.
Sous Debian, '''locate''' et '''find''' se trouvent dans le paquet '''findutils''', normalement installé par défaut.
[[Catégorie:Informatique]]

Dernière version du 7 mars 2010 à 19:52


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 (quel que soit son type) à 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 motif : -name et -iname

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 ("). Si l'on veut rechercher sans tenir compte de la casse, on utilise l'option -iname :

$ find répertoire -iname fichier

À la place du nom, on peut aussi spécifier un motif ; pour rechercher tous les fichiers d'en-tête C dans le répertoire répertoire on peut écrire :

$ find répertoire -name '*.h'

Par exemple, si j'ai une arborescence de fichiers :

répertoire1/fichier1
répertoire1/répertoire2/fichier1
répertoire1/répertoire2/Fichier1
répertoire1/répertoire2/fichier2
répertoire1/répertoire3/fichier1
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

Si je veux effectuer la même recherche, mais sans tenir compte de la casse, je tape :

$ find répertoire1 -iname fichier1

Et j'obtiens :

répertoire1/répertoire2/fichier1
répertoire1/répertoire2/Fichier1
répertoire1/répertoire3/fichier1
répertoire1/répertoire3/FICHIER1
répertoire1/fichier1

Si je veux chercher tous les fichiers dont le nom finit par le chiffre 3, je tape :

$ find répertoire1 -name '*3'

Et j'obtiens :

répertoire1/répertoire3
répertoire1/répertoire4/fichier3

À 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/Fichier1
répertoire1/répertoire2/fichier2
répertoire1/répertoire3
répertoire1/répertoire3/fichier1
répertoire1/répertoire3/FICHIER1
répertoire1/répertoire4
répertoire1/répertoire4/fichier3
répertoire1/fichier1

Recherche simple avec expression rationnelle : -regex et -iregex

Les options -name et -iname suffisent dans la plupart des cas, mais peuvent être limites si le motif à rechercher est très complexe.

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) -iname par -iregex et le nom du fichier par une… expression rationnelle, tout à fait !

Avertissement : dans le traitement de l'expression rationnelle, ce qui est pris en compte est l'ensemble de la ligne de sortie potentielle, et pas le nom du fichier. Par exemple si je cherche à partir du répertoire courant (find . -regex mon_expression), chaque ligne commencera par « ./ », et il faudra en tenir compte dans l'écriture de l'expression.

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 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" ».

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 est 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 courant :

$ 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 trouvaient traditionnellement dans le paquet findutils, normalement installé par défaut. Dans les versions récentes, locate est dans un paquet séparé, et mlocate, une version améliorée, est proposé par défaut.