当前位置:首页> 正文

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

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

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

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

这是我要尝试执行的操作(此操作行不通,因为管道结束了find命令):

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

尝试这个

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

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

1
find -exec some_script {} \;

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

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

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

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


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

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


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

1
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

要么

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

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


您可以使用另一种方式来完成此操作,但这也是相当的贫民窟。

使用shell选项extquote,您可以执行类似的操作来查找exec内容,然后将其传递给sh。

1
2
root@ifrit findtest # find -type f -exec echo ls $"|" cat \;|sh
filename

1
2
root@ifrit findtest # find -type f -exec echo ls $"|" cat $"|" xargs cat\;|sh
h

我只是想补充一下,因为至少我的可视化方式更接近OP最初在exec中使用管道的问题。


展开全文阅读

相关内容