Comment utiliser un tube 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 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 pipe termine la commande find):

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

Essaye ça

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

Sinon, vous pouvez essayer d’incorporer votre instruction exec dans un script sh et ensuite:

 find -exec some_script {} \; 

Une approche légèrement différente consisterait à 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 espaces)

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

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

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 hors de -exec ou en canalisant les résultats de find vers xargs comme suggéré par Palmin .)

L’utilisation de la commande find pour ce type de tâche n’est peut-être pas la meilleure solution. 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 

Comme cela génère une liste, ne devriez-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 du find -exec.

Il y a un autre moyen de le faire, mais c’est aussi un joli ghetto.

En utilisant l’option shell extquote, vous pouvez faire quelque chose de similaire pour créer des fichiers exec et les diriger 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 me suis juste dit que j’appendais que parce qu’au moins la façon dont je l’ai visualisé était plus proche de la question initiale de l’OP d’utiliser des tubes dans exec.