如何在exec参数中的管道中使用find命令?


76

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

具体来说,这是我要尝试执行的操作(此操作不起作用,因为管道结束了find命令):

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

Answers:


86

试试这个

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

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

find -exec some_script {} \;

15

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

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

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

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


4
在这里使用xargs的问题是我需要匹配的文件名。该命令确实找到匹配项,但是我不知道匹配哪个文件。
hoyhoy

4

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

请注意,使用的-exec效率很低。对于找到的每个文件,必须再次执行该命令。如果可以避免这种情况,那将更加有效。(例如,按照Palmin的建议,通过将的结果移到或grep外部-execfind移至。)xargs


1
通常情况下,避免多进程效率低下的另一种方法是使用xargs。如果碰巧需要单独的进程,则可以使用-i选项。我发现xargs更符合Unix模型。
乔恩·埃里克森

1
在xargs上使用AOL。mweerden,也许您应该通过考虑xargs的存在来更改最后一段。另请注意find和中都存在-0标志xargs
tzot

3

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

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

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的结果上。


那是行不通的,因为我需要-print才能工作。如果grep返回成功,则find打印文件名,否则不打印。
hoyhoy

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中使用管道的问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.