如何将 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 的存在来更改最后一段。还要注意find
和 xargs
中都存在的 -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中的find和grep命令对查找到的文件如何处理啊