78 votes

Comment utiliser un pipe dans le paramètre exec d'une commande find ?

J'essaie de construire une commande find pour traiter un ensemble de fichiers dans un répertoire en utilisant deux exécutables différents. Malheureusement, -exec sur find ne permet pas d'utiliser pipe ou même \| parce que l'interpréteur de commandes interprète ce caractère en premier.

Voici précisément ce que j'essaie de faire (ce qui ne fonctionne pas car pipe termine la commande find) :

find /path/to/jpgs -type f -exec jhead -v {} | grep 123 \; -print

88voto

Martín Marconcini Points 7420

Essayez ceci

find /path/to/jpgs -type f -exec sh -c 'jhead -v {} | grep 123' \; -print

Alternativement, vous pourriez essayer d'incorporer votre instruction exec à l'intérieur d'un script sh et ensuite faire :

find -exec some_script {} \;

15voto

Palmin Points 1281

Une approche légèrement différente serait d'utiliser xargs :

find /path/to/jpgs -type f -print0 | xargs -0 jhead -v | grep 123

que j'ai toujours trouvé un peu plus facile à comprendre et à adapter (les arguments -print0 et -0 sont nécessaires pour faire face aux noms de fichiers contenant des blancs)

Ce site puede (non testé) est plus efficace que l'utilisation de -exec car il transmet la liste des fichiers à xargs et xargs s'assure que la ligne de commande de jhead ne soit pas trop longue.

4 votes

Le problème avec l'utilisation de xargs ici est que j'ai besoin du nom du fichier qui correspond. Cette commande trouve bien les correspondances, mais je ne sais pas quel fichier correspond.

4voto

mweerden Points 4291

Avec -exec vous ne pouvez exécuter qu'un seul exécutable avec certains arguments, et non des commandes shell arbitraires. Pour contourner cela, vous pouvez utiliser sh -c '<shell command>' .

Veuillez noter que l'utilisation de -exec est assez inefficace. Pour chaque fichier trouvé, la commande doit être exécutée à nouveau. Il serait plus efficace d'éviter cela. (Par exemple, en déplaçant le grep en dehors de la -exec ou de canaliser les résultats de find a xargs comme suggéré par Palmin .)

1 votes

Une autre façon d'éviter l'inefficacité des processus multiples dans le cas général est d'utiliser xargs. Si vous avez besoin de processus séparés, vous pouvez utiliser l'option -i. Je trouve que xargs est plus en accord avec le modèle Unix.

1 votes

AOL sur l'utilisation de xargs. mweerden, vous devriez peut-être modifier votre dernier paragraphe en tenant compte de l'existence de xargs. Notez également le drapeau -0 qui existe à la fois dans find y xargs .

3voto

Dimitar Points 11

Utilisation de find pour ce type de tâche n'est peut-être pas la meilleure solution. J'utilise fréquemment la commande suivante pour trouver les fichiers qui contiennent les informations demandées :

for i in dist/*.jar; do echo ">> $i"; jar -tf "$i" | grep BeanException; done

1voto

Xetius Points 10445

Comme ces sorties une liste ne serait pas vous :

find /path/to/jpgs -type f -exec jhead -v {} \; | grep 123

ou

find /path/to/jpgs -type f -print -exec jhead -v {} \; | grep 123

Mets ton grep sur les résultats du find -exec.

0 votes

Cela ne fonctionne pas parce que j'ai besoin de l'option -print pour fonctionner. Si grep renvoie un succès, alors find imprime le nom du fichier, sinon il ne le fait pas.

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