如何在linux find -exec命令中包含管道| ?

时间:2022-01-17 20:32:18

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

这不是工作。这能在find中实现吗?还是我需要xargs?

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

4 个解决方案

#1


114  

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).

将管道符号解释为运行多个进程并将一个进程的输出导入另一个进程的输入的指令是shell (/bin/sh或等效的)的职责。

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

在您的示例中,您可以选择使用顶层shell来执行如下操作:

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.

就效率而言,该结果需要调用find、多次调用zcat和一次调用agrep。

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

这将导致只产生一个协议进程,该进程将处理无数次调用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.)

它使用管道构造一个命令列表来执行,然后将这些命令发送到一个新的shell以实际执行。(省略最后的“| sh”是调试或执行类似这样的命令行枯燥运行的好方法。)

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

就效率而言,该结果需要调用find、sh、无数次调用zcat和无数次调用agrep。

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

就命令调用数量而言,最有效的解决方案是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.

…这需要一次查找调用、一次xargs调用、几个zcat调用和一次agrep调用。

#2


206  

the solution is easy: execute via sh

解决方案很简单:通过sh执行

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

#3


15  

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

#4


8  

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

您还可以将管道连接到一个while循环,该循环可以对查找位置的文件执行多个操作。因此,这里有一个用于在jar存档中查找给定java类文件的文件夹,该文件夹中包含大量jar文件的发行版

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:

关键在于while循环包含多个命令,引用由分号分隔的传入文件名,这些命令可以包含管道。在这个例子中,我回显匹配文件的名称,然后列出对给定类名进行归档过滤的内容。输出:

/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

/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。类/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.

在我的bash shell (xubuntu10.04/xfce)中,它确实使匹配的类名加粗,因为fgrep突出显示匹配的字符串;这使得扫描搜索的数百个jar文件列表变得非常容易,并且很容易看到任何匹配。

on windows you can do the same thing with:

在windows上你也可以这样做:

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...

注意,在windows上的命令分隔符是'&' not ';' ',并且'@'抑制命令的回音,以提供一个整洁的输出,就像上面的linux查找输出;尽管findstr并没有使匹配的字符串加粗,因此您必须在输出中稍微靠近一点以查看匹配的类名。事实证明,windows的“for”命令知道很多技巧,比如在文本文件中循环……

enjoy

享受

#1


114  

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).

将管道符号解释为运行多个进程并将一个进程的输出导入另一个进程的输入的指令是shell (/bin/sh或等效的)的职责。

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

在您的示例中,您可以选择使用顶层shell来执行如下操作:

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.

就效率而言,该结果需要调用find、多次调用zcat和一次调用agrep。

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

这将导致只产生一个协议进程,该进程将处理无数次调用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.)

它使用管道构造一个命令列表来执行,然后将这些命令发送到一个新的shell以实际执行。(省略最后的“| sh”是调试或执行类似这样的命令行枯燥运行的好方法。)

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

就效率而言,该结果需要调用find、sh、无数次调用zcat和无数次调用agrep。

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

就命令调用数量而言,最有效的解决方案是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.

…这需要一次查找调用、一次xargs调用、几个zcat调用和一次agrep调用。

#2


206  

the solution is easy: execute via sh

解决方案很简单:通过sh执行

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

#3


15  

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

#4


8  

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

您还可以将管道连接到一个while循环,该循环可以对查找位置的文件执行多个操作。因此,这里有一个用于在jar存档中查找给定java类文件的文件夹,该文件夹中包含大量jar文件的发行版

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:

关键在于while循环包含多个命令,引用由分号分隔的传入文件名,这些命令可以包含管道。在这个例子中,我回显匹配文件的名称,然后列出对给定类名进行归档过滤的内容。输出:

/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

/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。类/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.

在我的bash shell (xubuntu10.04/xfce)中,它确实使匹配的类名加粗,因为fgrep突出显示匹配的字符串;这使得扫描搜索的数百个jar文件列表变得非常容易,并且很容易看到任何匹配。

on windows you can do the same thing with:

在windows上你也可以这样做:

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...

注意,在windows上的命令分隔符是'&' not ';' ',并且'@'抑制命令的回音,以提供一个整洁的输出,就像上面的linux查找输出;尽管findstr并没有使匹配的字符串加粗,因此您必须在输出中稍微靠近一点以查看匹配的类名。事实证明,windows的“for”命令知道很多技巧,比如在文本文件中循环……

enjoy

享受