如何将 exec 参数中的管道用于查找命令?

Posted

技术标签:

【中文标题】如何将 exec 参数中的管道用于查找命令?【英文标题】:How do I use a pipe in the exec parameter for a find command? 【发布时间】:2010-09-08 21:20:32 【问题描述】:

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

这就是我想要做的(这不起作用,因为管道结束了 find 命令):

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

【问题讨论】:

【参考方案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 打印文件名,否则不打印。【参考方案2】:

试试这个

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

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

find -exec some_script  \;

【讨论】:

【参考方案3】:

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

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

【讨论】:

在一般情况下避免多进程低效的另一种方法是使用 xargs。如果您碰巧需要单独的进程,则可以使用 -i 选项。我发现 xargs 更符合 Unix 模型。 AOL 关于 xargs 的使用。 mweerden,也许您应该考虑到 xargs 的存在来更改最后一段。还要注意 findxargs 中都存在的 -0 标志。【参考方案4】:

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

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

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

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

【讨论】:

这里使用 xargs 的问题是我需要匹配的文件名。此命令确实找到匹配项,但我不知道哪个文件匹配。【参考方案5】:

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

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

【讨论】:

【参考方案6】:

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

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

【讨论】:

以上是关于如何将 exec 参数中的管道用于查找命令?的主要内容,如果未能解决你的问题,请参考以下文章

linux中的查找命令

(转)linux下find查找命令用法

Linux中的find和grep命令对查找到的文件如何处理啊

管道命令

Linux中的find和grep命令对查找到的文件如何处理啊

全网最详细的Linux命令系列-Find命令