web-dev-qa-db-fra.com

Comment utiliser un canal dans le paramètre exec pour une commande find?

J'essaie de construire une commande find pour traiter un tas de fichiers dans un répertoire en utilisant deux exécutables différents. Malheureusement, -exec on find ne permet pas d'utiliser le pipe ou même \| car le shell interprète ce caractère en premier.

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

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

Essaye ça

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

Alternativement, vous pouvez essayer d'incorporer votre instruction exec dans un script sh, puis faire:

find -exec some_script {} \;
79
Martin Marconcini

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 gérer les noms de fichiers contenant des blancs)

Cela pourrait (non testé) être plus efficace que d'utiliser -exec car il dirigera la liste des fichiers vers xargs et xargs s'assure que la ligne de commande jhead ne soit pas trop longue.

12
Palmin

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

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

3
mweerden

Utiliser la commande find pour ce type de tâche n'est peut-être pas la meilleure alternative. J'utilise fréquemment la commande suivante pour rechercher des fichiers contenant les informations demandées:

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

Comme cela génère une liste, ne voudriez-vous pas:

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

ou

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

Mettez votre grep sur les résultats de la recherche -exec.

1
Xetius

Il y a une autre façon de le faire, mais c'est aussi un joli ghetto.

En utilisant l'option Shell extquote, vous pouvez faire quelque chose de similaire à ceci afin de trouver des trucs d'exec et de les rediriger vers sh.

root@ifrit findtest # find -type f -exec echo ls $"|" cat \;|sh
filename


root@ifrit findtest # find -type f -exec echo ls $"|" cat $"|" xargs cat\;|sh
h

Je pensais juste ajouter que parce qu'au moins la façon dont je le visualisais, c'était plus proche de la question originale de l'OP d'utiliser des tuyaux dans exec.

0
linuxgeek