208 votes

À l’aide de point-virgule ( ;) vs plus (+) avec exec dans trouver

Pourquoi y a-t-il une différence de production entre l'utilisation

 find . -exec ls '{}' \+
 

et

 find . -exec ls '{}' \;
 

J'ai eu:

 $ find . -exec ls  \{\} \+
./file1  ./file2

.:
file1  file2  testdir1

./testdir1:
testdir2

./testdir1/testdir2:


$ find . -exec ls  \{\} \;
file1  file2  testdir1
testdir2
./file2
./file1
 

329voto

Martin Points 13951

Cela pourrait être mieux illustré par un exemple. Disons que find récupère ces fichiers:

 file1
file2
file3
 

Utilisation de -exec avec un point-virgule ( find . -exec ls '{}' \; ), sera exécuté

 ls file1
ls file2
ls file3
 

Mais si vous utilisez plutôt un signe plus ( find . -exec ls '{}' \+ ), tous les noms de fichiers seront transmis en tant qu'arguments à une seule commande:

 ls file1 file2 file3
 

52voto

Johnsyweb Points 45395

Toutes les réponses sont correctes. Je vous présente donc comme un plus clair (pour moi) la démonstration de l'un comportement qui est décrit à l'aide d' echo plutôt que d' ls:

Avec un point-virgule, la commande echo est appelé qu'une seule fois par fichier (ou d'un autre objet filesystem) trouvés:

$ find . -name 'test*' -exec echo {} \;
./test.c
./test.cpp
./test.new
./test.php
./test.py
./test.sh

Avec un plus, la commande echo est appelée une seule fois. Chaque fichier trouvé est passé en argument.

$ find . -name 'test*' -exec echo {} \+
./test.c ./test.cpp ./test.new ./test.php ./test.py ./test.sh

Si find tourne un grand nombre de résultats, vous pouvez trouver que la commande étant appelés bobines d'induction sur le nombre d'arguments.

39voto

matchew Points 5196

de l'homme

-exec commande ;

Exécution de la commande; vrai si 0 statut est retourné. Tous les suivants arguments à trouver sont prises pour être les arguments de la commande jusqu'à ce que un argument consistant ';' est rencontré. La chaîne de caractères '{}' est remplacé par le nom du fichier en cours en cours de traitement partout il se produit dans les arguments de la commande, et pas seulement dans les arguments où il est seul, comme dans certaines versions de trouver. Ces deux constructions pourraient avoir besoin d'être échappés (avec un '\') ou d'une citation à les protéger de l'expansion par le shell. Voir les EXEMPLES de la sec- tion pour des exemples de l'utilisation de l' "- exec " option. La spéci- fied de commande est exécuté une fois pour chaque fichier correspondant. La commande est exécutée dans le répertoire de démarrage. Il y a des inévitables les problèmes de sécurité qui entourent l'utilisation de l'option-exec; vous devrait utiliser l'-execdir option à la place.

-exec commande {} +

Cette variante de l'option-exec exécute la commande spécifiée sur les fichiers sélectionnés, mais la ligne de commande est construit en ajoutant chaque nom de fichier sélectionné à la fin; le nombre total de invoca- tions de la commande sera beaucoup moins que le nombre de fichiers correspondants. La ligne de commande est construit de la même façon que xargs construit ses lignes de commande. Une seule instance de '{}' est autorisé à l'intérieur de la commande. La commande est exécutée dans l' répertoire de départ.

donc, la façon dont je le comprends, \, qui exécute des commandes séparées et + ajoute chaque nom. c'est en fait la façon dont elle est exécutée, comme le \ est une évasion de sorte que son

ls testdir1; ls testdir2 

vs

ls testdir1 testdir2

faire ci-dessus dans ma coquille en miroir de la sortie de votre question.

Mise à JOUR 2

Alors, pourquoi voudriez-vous d'utiliser +

dire que j'ai deux fichiers 1.tmp et 2.tmp

1.tmp:

1
2
3

2.tmp:

0
2
3

l'exécution de

 find *.tmp -exec diff {} \;
> diff: missing operand after `1.tmp'
> diff: Try `diff --help' for more information.
> diff: missing operand after `2.tmp'
> diff: Try `diff --help' for more information.

où si vous utilisez + et concaténer les trouve des résultats comme suit:

find *.tmp -exec diff {} \+
1c1,3
< 1
---
> 0
> 2
> 30

donc dans ce cas c'est la différence entre les diff 1.tmp; diff 2.tmp et diff 1.tmp 2.tmp

Il y a des cas où \; est approprié et + sera nécessaire. à l'aide de + avec rm est l'un de ces cas, où si vous êtes en train de supprimer un grand nombre de fichiers de vitesse dans beaucoup améliorée au cours de ;. J'aime toujours apprendre plus au sujet de trouver, c'est un outil puissant et pratique util j'espère que c'est suffisant pour expliquer les différences.

13voto

Charlie Martin Points 62306

Voici l'affaire: trouver a une syntaxe spéciale. Vous utilisez l' {} comme ils le sont parce qu'ils ont un sens pour trouver le nom de chemin du fichier trouvé et (la plupart) des coquilles de ne pas les interpréter autrement. Vous avez besoin de la barre oblique inverse \; parce que le point-virgule a un sens pour la coquille, qui le mange avant de trouver le peuvent. Donc, ce que trouver veut voir APRÈS le shell est fait, dans la liste des arguments passés au programme C, est

"-exec", "rm", "{}", ";"

mais vous avez besoin d' \; sur la ligne de commande pour obtenir un point-virgule à travers la coquille de l'argumentation.

Vous pouvez vous en sortir avec \{\} parce que le shell-cité de l'interprétation de l' \{\} est juste {}. De même, vous pouvez utiliser '{}'.

Ce que vous ne peut pas faire est d'utiliser

 -exec 'rm {} ;'

parce que le shell interprète que comme un argument,

"-exec", "rm {} ;"

et "rm {} ;" n'est-ce pas le nom d'une commande. (Au moins, sauf si quelqu'un est vraiment vissage autour de vous).

Mise à jour

la différence est entre

$ ls file1
$ ls file2

et

$ ls file1 file2

Le + est catenating les noms ont une ligne de commande.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X