How do I include a pipe | in my linux find -exec command?

The job of interpreting the pipe symbol as an instruction to run multiple processes and pipe the output of one process into the input of another process is the responsibility of the shell (/bin/sh or equivalent).

In your example you can either choose to use your top level shell to perform the piping like so:

find -name 'file_*' -follow -type f -exec zcat {} \; | agrep -dEOE 'grep'

In terms of efficiency this results costs one invocation of find, numerous invocations of zcat, and one invocation of agrep.

This would result in only a single agrep process being spawned which would process all the output produced by numerous invocations of zcat.

If you for some reason would like to invoke agrep multiple times, you can do:

find . -name 'file_*' -follow -type f \
    -printf "zcat %p | agrep -dEOE 'grep'\n" | sh

This constructs a list of commands using pipes to execute, then sends these to a new shell to actually be executed. (Omitting the final "| sh" is a nice way to debug or perform dry runs of command lines like this.)

In terms of efficiency this results costs one invocation of find, one invocation of sh, numerous invocations of zcat and numerous invocations of agrep.

The most efficient solution in terms of number of command invocations is the suggestion from Paul Tomblin:

find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'

... which costs one invocation of find, one invocation of xargs, a few invocations of zcat and one invocation of agrep.


the solution is easy: execute via sh

... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \;