|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||
|
Membre du Club
![]() Inscription : juin 2006 Messages : 206 ![]() |
Bonjour à tous,
Je souhaiterais faire un bout de script qui me liste tous les fichiers d'un répertoire, MAIS SANS le chemin. Je m'explique : find repertoire -name 'fichier*', va me donner une liste comme ci dessous : repertoire/fichier1 repertoire/fichier2 Or je voudrais juste fichier1 fichier2 Etant donné que je sais que je liste les fichiers de repertoire... Pour le moment mon script est le suivant : Code :
|
||
|
|
00
|
|
|
#2 |
![]() ![]() Inscription : juillet 2004 Messages : 2 246 ![]() |
Bonjour.
ça aide ?
__________________
Toutes les vertus des hommes se perdent dans l’intérêt comme les fleuves se perdent dans la mer. |
|
|
00
|
|
|
#3 | |||
|
Expert Confirmé Sénior
![]() francois Ingénieur systèmes et réseaux Inscription : juillet 2006 Messages : 3 546 ![]() |
Citation:
il faut faire Code :
find ./chemin/ -type f -print | awk -F '/' '{print $NF}' enfin à moins de vouloir multiplier le temps d'exécution par le nombre de fichier trouvés.
|
|||
|
|
00
|
|
|
#4 | |
|
Membre Expert
![]() Inscription : mars 2002 Messages : 946 ![]() |
Citation:
Il y a des cas où on peut vouloir effectuer une action sur chaque élément, et l'option -exec n'a pas toujours la souplesse que l'on souhaite. D'un point de vue théorique, la complexité en temps reste la même. La complexité en espace est plus importante, mais c'est parce qu'il utilise for plutôt que while. Et faire un find | while ne me choque pas plus que ça. |
|
|
|
00
|
|
|
#5 | ||
|
Expert Confirmé Sénior
![]() francois Ingénieur systèmes et réseaux Inscription : juillet 2006 Messages : 3 546 ![]() |
Citation:
Citation:
en formation un find dans un boucle ou |while c'est direct le zéro pointé. le formateur se casse même pas à lire la suite du code.
|
||
|
|
00
|
|
|
#6 | ||
|
Membre Expert
![]() Inscription : mars 2002 Messages : 946 ![]() |
Si.
En fait, ça dépend du travail à effectuer. Mais compare les 2 lignes suivantes (on est d'accord, ça ne sert à rien, mais c'est pour comparer les temps) : Code :
While et read sont des builtin, et selon le contenu du script, il fork ou non. Dans tous les cas, le exec doit faire du fork. La première t'économise au final n fork (et cela reste vrai pour les script plus complexes). De plus, avoir un while offre bien plus de souplesse. Par exemple, on peut définir une fonction dans le script et l'appeler en boucle. Avec find, tu dois passer par un fichier extérieur... et forker autant de fois (l'appel d'une fonction locale n'engendre pas de fork). Au final, je ne dis pas qu'il faut toujours utiliser telle méthode, ça dépend des cas et de ce que l'on veut faire. D'une manière générale, privilégier la lisibilité du code est une bonne chose. Donc, pour un simple exécutable à appeler -exec est bien ; pour les cas plus complexes, while est bien plus clair. Si le formateur met 0 par incompétence, tu peux lui signaler. |
||
|
|
00
|
|
|
#7 |
|
Membre émérite
![]() Inscription : mai 2004 Messages : 709 ![]() |
Pourquoi pas simplement:
__________________
:q :q! :wq :w :w! :wq! :quit :quit! :help help helpquit quit quithelp :quitplease :quitnow :leave :shit ^X^C ^C ^D ^Z ^Q QUITDAMMIT Jabber: ripat at im.apinc.org |
|
|
00
|
|
|
#8 |
![]() ![]() Arnaud FeltzDéveloppeur .NET Inscription : août 2005 Messages : 5 204 ![]() |
@LLB : j'ai testé la différence entre les deux commandes, mais "bizzarement" quand on fait un grep avec les deux commandes que t'as données, c'est celle avec l'option -exec de la commande find qui est plus rapide.
Normal? P.S : je tiens à dire que j'ai envoyé les sorties dans deux fichiers différents et fait un diff dessus, aucune différence
__________________
C'est par l'adresse que vaut le bûcheron, bien plus que par la force. Homère Installation de Code::Blocks sous Debian à partir de Nightly Builds
|
|
00
|
|
|
#9 |
|
Membre Expert
![]() Inscription : mars 2002 Messages : 946 ![]() |
Tu as juste remplacé echo par grep ?
Dans ce cas, c'est normal que le résultat change : grep est un binaire externe. Donc, que ce soit pour le -exec ou pour le while, il y a le même nombre de forks (à un ou deux près). Le -exec est plus rapide parce qu'il peut appeler directement le grep, tandis que le while passe par du read. Il y a donc une couche supplémentaire. Mais je suppose que la différence entre les deux n'est pas énorme. Ma comparaison visait à montrer que, lorsqu'il y a des builtins, while peut être (parfois beaucoup) plus rapide. Avec echo, la différence était flagrante. Maintenant, si tu mets ton grep dans un script shell (externe) et tu fais le moins -exec sur ce script shell, je suppose que le -exec sera plus lent : il y aura en tout n forks de plus. |
|
|
00
|
|
|
#10 |
![]() ![]() Arnaud FeltzDéveloppeur .NET Inscription : août 2005 Messages : 5 204 ![]() |
pour cette explication Je tacherai de m'en souvenir
__________________
C'est par l'adresse que vaut le bûcheron, bien plus que par la force. Homère Installation de Code::Blocks sous Debian à partir de Nightly Builds
|
|
00
|
|
|
#11 |
|
Membre Expert
![]() Inscription : mars 2002 Messages : 946 ![]() |
Explication un peu plus détaillée. J'avais commencé à la taper avant que tu répondes. Normalement, tu n'as pas besoin "de t'en souvenir", il y a juste à comprendre (d'ailleurs, je n'avais jamais réfléchi à ce cas avant hier).
Le but de ces exemples n'est donc pas vraiment d'optimiser le script (dans 80% des cas, on s'en fiche), mais c'est important de bien comprendre comment fonctionne un shell. Code :
time find . | while read file; do echo $file; done Il y a un fork pour le find. Ensuite, pour chaque fichier, il faut faire echo. Echo n'étant pas une builtin de find, find n'a pas d'autre choix que de faire appel au binaire echo. Donc, find est contraint de faire un fork par fichier trouvé. D'ailleurs, dans cet exemple là, on voit bien l'intérêt d'avoir un binaire echo. Et la raison d'avoir une builtin echo (dans les shells) est évidente : le gain en performance est très important. Il y a un fork pour le find. Printf étant une builtin de find, il n'y a pas besoin d'autre fork. Code :
find . | while read file; do grep toto $file; done (grep.sh est un script shell qui appelle grep) Il y a un fork pour le find. Ensuite, pour chaque fichier, il est nécessaire de faire un fork et d'appeler le shell. Puis, le shell doit faire à nouveau un fork pour appeler le grep. On a donc 2 * n forks. Ainsi, find | while a pour avantages : - accès aux builtins du shell. Par exemple, si tu voulais lancer alias en boucle sur les résultats, tu n'aurais pas eu le choix. - pour ce qui nécessite plusieurs lignes de shell, je pense qu'on gagne en rapidité ; et surtout, en clarté (pas besoin de fichier extérieur). Pour les cas basiques (90% des cas), -exec est plus adapté. |
|
|
00
|
|
|
#12 |
![]() ![]() Arnaud FeltzDéveloppeur .NET Inscription : août 2005 Messages : 5 204 ![]() |
Qu'une seule chose à dire, merci
C'est on ne peut plus clair et je me coucherais moins bête ce soir
__________________
C'est par l'adresse que vaut le bûcheron, bien plus que par la force. Homère Installation de Code::Blocks sous Debian à partir de Nightly Builds
|
|
00
|
|
|
#13 |
|
Membre du Club
![]() Inscription : juin 2006 Messages : 206 ![]() |
BOnjour,
Je suis un peu perdu, la discussion est partie dans de très hautes sphères pour moi. Pour le moment, il faut que je me familiarise avec les commandes linux. Reprenons le problème original : J'ai besoin d'exécuter une commande pour chaque nom de fichier que je trouve, d'où l'intérêt de la boucle. Je veux bien déplacer le find or de la boucle for, mais comment faire pour ecrire le nom des fichiers que j'ai trouver dans UN fichier nommé liste.txt par exemple? Je vais essayer de regarder toutes les options que vous voulez me faire ingurgiter avec man
|
|
|
00
|
|
|
#14 |
|
Membre Expert
![]() Inscription : mars 2002 Messages : 946 ![]() |
redirige la sortie standard de la commande dans le fichier spécifié.
Avec find, tu devrais t'en sortir. |
|
|
00
|
|
|
#15 |
|
Membre du Club
![]() Inscription : juin 2006 Messages : 206 ![]() |
Ok, je viens de tester, ca marche bien,
merci à vous Votre discussion m'a permis de comprendre qu'en fait je n'avais pas besoin de faire de boucle avec find. Pire, ce que je ne comprend pas c'est comment ca se fait que je n'ai pas fait de boucle infinie??? |
|
|
00
|
|
|
#16 |
|
Membre Expert
![]() Inscription : mars 2002 Messages : 946 ![]() |
Un for n'est pas un while. Il n'y a qu'en C (et ses dérivés) que le for est évalué à chaque boucle.
En Shell, dans "for i in `cmd`", cmd n'est évalué qu'une seule fois. Et heureusement ! En pratique, le shell évalue cmd, mémorise sa sortie (donc, on évite le for quand la sortie est très longue, du genre le contenu d'un fichier) et boucle sur chacun des résultats. Il n'y a donc pas de risque de boucle infinie. |
|
|
00
|
Copyright © 2000-2012 - www.developpez.com