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
How do I use a pipe in the exec parameter for a find command?
提问by hoyhoy
I'm trying to construct a find command to process a bunch of files in a directory using two different executables. Unfortunately, -exec
on 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 -exec
you 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 -exec
is 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 grep
outside the -exec
or piping the results of find
to xargs
as suggested by Palmin.)
请注意,使用 的-exec
效率非常低。对于找到的每个文件,必须再次执行该命令。如果可以避免这种情况,效率会更高。(例如,通过移动grep
外-exec
或配管的结果find
,以xargs
所建议Palmin。)
回答by Dimitar
Using find
command 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 中使用管道的原始问题。