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

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

find /path/to/jpgs -type f -exec jhead -v {} | grep 123 \; -print
有帮助吗?

解决方案

尝试这个

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

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

find -exec some_script {} \;

其他提示

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

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

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

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

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

请注意,使用 -exec 效率相当低。对于找到的每个文件,都必须再次执行该命令。如果能避免这种情况,效率会更高。(例如,通过移动 grep 之外的 -exec 或通过管道传输结果 findxargs 正如建议的 帕尔明.)

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

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

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

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top