Il compito di interpretare il simbolo pipe come un'istruzione per eseguire più processi e convogliare l'output di un processo nell'input di un altro processo è responsabilità della shell (/bin/sh o equivalente).
Nel tuo esempio puoi scegliere di utilizzare la tua shell di primo livello per eseguire il piping in questo modo:
find -name 'file_*' -follow -type f -exec zcat {} \; | agrep -dEOE 'grep'
In termini di efficienza, questo risultato costa un'invocazione di find, numerose invocazioni di zcat e un'invocazione di agrep.
Ciò comporterebbe la generazione di un solo processo agrep che elaborerebbe tutto l'output prodotto da numerose invocazioni di zcat.
Se per qualche motivo desideri invocare agrep più volte, puoi fare:
find . -name 'file_*' -follow -type f \
-printf "zcat %p | agrep -dEOE 'grep'\n" | sh
Questo costruisce un elenco di comandi utilizzando pipe da eseguire, quindi li invia a una nuova shell per essere effettivamente eseguiti. (Omettere l'ultimo "| sh" è un buon modo per eseguire il debug o eseguire test di righe di comando come questa.)
In termini di efficienza, questo risultato costa un'invocazione di find, un'invocazione di sh, numerose invocazioni di zcat e numerose invocazioni di agrep.
La soluzione più efficiente in termini di numero di invocazioni di comandi è il suggerimento di Paul Tomblin:
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'
... che costa un'invocazione di find, un'invocazione di xargs, alcune invocazioni di zcat e un'invocazione di agrep.
la soluzione è semplice:eseguire tramite sh
... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \;