bash 如何在 exec 参数中使用管道作为 find 命令?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/62044/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 17:37:23  来源:igfitidea点击:

How do I use a pipe in the exec parameter for a find command?

bashshellfind

提问by hoyhoy

I'm trying to construct a find command to process a bunch of files in a directory using two different executables. Unfortunately, -execon find doesn't allow to use pipe or even \|because the shell interprets that character first.

我正在尝试构建一个 find 命令来使用两个不同的可执行文件处理目录中的一堆文件。不幸的是,-exec在 find 不允许使用管道,甚至\|因为外壳首先解释该字符。

Here is specifically what I'm trying to do (which doesn't work because pipe ends the find command):

这是我正在尝试做的具体操作(这不起作用,因为管道结束了 find 命令):

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

回答by Martin Marconcini

Try this

尝试这个

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

Alternatively you could try to embed your exec statement inside a sh script and then do:

或者,您可以尝试将 exec 语句嵌入到 sh 脚本中,然后执行以下操作:

find -exec some_script {} \;

回答by Palmin

A slightly different approach would be to use xargs:

一种稍微不同的方法是使用 xargs:

find /path/to/jpgs -type f -print0 | xargs -0 jhead -v | grep 123

which I always found a bit easier to understand and to adapt (the -print0 and -0 arguments are necessary to cope with filenames containing blanks)

我总是发现它更容易理解和适应( -print0 和 -0 参数对于处理包含空格的文件名是必要的)

This might(not tested) be more effective than using -exec because it will pipe the list of files to xargs and xargs makes sure that the jhead commandline does not get too long.

可能(未经测试)比使用 -exec 更有效,因为它会将文件列表通过管道传输到 xargs,而 xargs 确保 jhead 命令行不会变得太长。

回答by mweerden

With -execyou can only run a single executable with some arguments, not arbitrary shell commands. To circumvent this, you can use sh -c '<shell command>'.

随着-exec你只能运行一些争论,不是任意的shell命令的可执行文件。为了避免这种情况,您可以使用sh -c '<shell command>'.

Do note that the use of -execis quite inefficient. For each file that is found, the command has to be executed again. It would be more efficient if you can avoid this. (For example, by moving the grepoutside the -execor piping the results of findto xargsas suggested by Palmin.)

请注意,使用 的-exec效率非常低。对于找到的每个文件,必须再次执行该命令。如果可以避免这种情况,效率会更高。(例如,通过移动grep-exec或配管的结果find,以xargs所建议Palmin。)

回答by Dimitar

Using findcommand for this type of a task is maybe not the best alternative. I use the following command frequently to find files that contain the requested information:

find对此类任务使用命令可能不是最佳选择。我经常使用以下命令来查找包含请求信息的文件:

for i in dist/*.jar; do echo ">> $i"; jar -tf "$i" | grep BeanException; done

回答by Xetius

As this outputs a list would you not :

由于这会输出一个列表,你会不会:

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

or

或者

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

Put your grep on the results of the find -exec.

将您的 grep 放在 find -exec 的结果上。

回答by linuxgeek

There is kind of another way you can do it but it is also pretty ghetto.

还有另一种方法可以做到,但它也是非常贫民窟。

Using the shell option extquote you can do something similar to this in order to make find exec stuff and then pipe it to sh.

使用 shell 选项 extquote 您可以执行与此类似的操作,以便查找 exec 内容,然后通过管道将其传送到 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

I just figured I'd add that because at least the way i visualized it, it was closer to the OP's original question of using pipes within exec.

我只是想我会添加它,因为至少我将它可视化的方式,它更接近 OP 在 exec 中使用管道的原始问题。