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

This isn't working. Can this be done in find? Or do I need to xargs?

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

This question is related to linux command-line

The answer is


I found that running a string shell command (sh -c) works best, for example:

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

If you are looking for a simple alternative, this can be done using a loop:

for i in $(find -name 'file_*' -follow -type f); do
  zcat $i | agrep -dEOE 'grep'
done

or, more general and easy to understand form:

for i in $(YOUR_FIND_COMMAND); do
  YOUR_EXEC_COMMAND_AND_PIPES
done

and replace any {} by $i in YOUR_EXEC_COMMAND_AND_PIPES


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

the solution is easy: execute via sh

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

I found that running a string shell command (sh -c) works best, for example:

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

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

the solution is easy: execute via sh

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

If you are looking for a simple alternative, this can be done using a loop:

for i in $(find -name 'file_*' -follow -type f); do
  zcat $i | agrep -dEOE 'grep'
done

or, more general and easy to understand form:

for i in $(YOUR_FIND_COMMAND); do
  YOUR_EXEC_COMMAND_AND_PIPES
done

and replace any {} by $i in YOUR_EXEC_COMMAND_AND_PIPES


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

You can also pipe to a while loop that can do multiple actions on the file which find locates. So here is one for looking in jar archives for a given java class file in folder with a large distro of jar files

find /usr/lib/eclipse/plugins -type f -name \*.jar | while read jar; do echo $jar; jar tf $jar | fgrep IObservableList ; done

the key point being that the while loop contains multiple commands referencing the passed in file name separated by semicolon and these commands can include pipes. So in that example I echo the name of the matching file then list what is in the archive filtering for a given class name. The output looks like:

/usr/lib/eclipse/plugins/org.eclipse.core.contenttype.source_3.4.1.R35x_v20090826-0451.jar /usr/lib/eclipse/plugins/org.eclipse.core.databinding.observable_1.2.0.M20090902-0800.jar org/eclipse/core/databinding/observable/list/IObservableList.class /usr/lib/eclipse/plugins/org.eclipse.search.source_3.5.1.r351_v20090708-0800.jar /usr/lib/eclipse/plugins/org.eclipse.jdt.apt.core.source_3.3.202.R35x_v20091130-2300.jar /usr/lib/eclipse/plugins/org.eclipse.cvs.source_1.0.400.v201002111343.jar /usr/lib/eclipse/plugins/org.eclipse.help.appserver_3.1.400.v20090429_1800.jar

in my bash shell (xubuntu10.04/xfce) it really does make the matched classname bold as the fgrep highlights the matched string; this makes it really easy to scan down the list of hundreds of jar files that were searched and easily see any matches.

on windows you can do the same thing with:

for /R %j in (*.jar) do @echo %j & @jar tf %j | findstr IObservableList

note that in that on windows the command separator is '&' not ';' and that the '@' suppresses the echo of the command to give a tidy output just like the linux find output above; although findstr is not make the matched string bold so you have to look a bit closer at the output to see the matched class name. It turns out that the windows 'for' command knows quite a few tricks such as looping through text files...

enjoy


the solution is easy: execute via sh

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

You can also pipe to a while loop that can do multiple actions on the file which find locates. So here is one for looking in jar archives for a given java class file in folder with a large distro of jar files

find /usr/lib/eclipse/plugins -type f -name \*.jar | while read jar; do echo $jar; jar tf $jar | fgrep IObservableList ; done

the key point being that the while loop contains multiple commands referencing the passed in file name separated by semicolon and these commands can include pipes. So in that example I echo the name of the matching file then list what is in the archive filtering for a given class name. The output looks like:

/usr/lib/eclipse/plugins/org.eclipse.core.contenttype.source_3.4.1.R35x_v20090826-0451.jar /usr/lib/eclipse/plugins/org.eclipse.core.databinding.observable_1.2.0.M20090902-0800.jar org/eclipse/core/databinding/observable/list/IObservableList.class /usr/lib/eclipse/plugins/org.eclipse.search.source_3.5.1.r351_v20090708-0800.jar /usr/lib/eclipse/plugins/org.eclipse.jdt.apt.core.source_3.3.202.R35x_v20091130-2300.jar /usr/lib/eclipse/plugins/org.eclipse.cvs.source_1.0.400.v201002111343.jar /usr/lib/eclipse/plugins/org.eclipse.help.appserver_3.1.400.v20090429_1800.jar

in my bash shell (xubuntu10.04/xfce) it really does make the matched classname bold as the fgrep highlights the matched string; this makes it really easy to scan down the list of hundreds of jar files that were searched and easily see any matches.

on windows you can do the same thing with:

for /R %j in (*.jar) do @echo %j & @jar tf %j | findstr IObservableList

note that in that on windows the command separator is '&' not ';' and that the '@' suppresses the echo of the command to give a tidy output just like the linux find output above; although findstr is not make the matched string bold so you have to look a bit closer at the output to see the matched class name. It turns out that the windows 'for' command knows quite a few tricks such as looping through text files...

enjoy


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