78

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

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

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

6 回答 6

88

试试这个

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

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

find -exec some_script {} \;
于 2008-09-15T09:54:10.147 回答
15

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

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

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

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

于 2008-09-15T10:52:50.723 回答
4

-exec您只能运行带有一些参数的单个可执行文件,而不是任意的 shell 命令。为了避免这种情况,您可以使用sh -c '<shell command>'.

请注意,使用的-exec效率非常低。对于找到的每个文件,必须再次执行该命令。如果你能避免这种情况会更有效率。(例如,按照 Palmin 的建议,通过移动外部管道grep-exec结果。)findxargs

于 2008-09-15T09:56:30.953 回答
3

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

for i in dist/*.jar; do echo ">> $i"; jar -tf "$i" | grep BeanException; done
于 2011-02-27T03:29:00.953 回答
1

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

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

或者

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

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

于 2008-09-15T09:52:47.797 回答
0

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

使用 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

我只是想我会补充一点,因为至少在我想象它的方式上,它更接近于 OP 在 exec 中使用管道的原始问题。

于 2018-02-01T15:16:08.003 回答