find -exec 中管道和重定向输出的正确位置?

Sti*_*lez 3 shell freebsd find io-redirection

我在 FreeBSD 上使用控制台中find-exec选项(例如,find . -exec sha1 {} \;)。

  1. 我如何正确放置(如果需要,转义)重定向和其他在语法上适用于 exec 命令或 find 命令的执行控制符号,例如 > >> | 和 &,我可能希望符号在不同场合应用于 thefindexec命令?

  2. 在同一主题上,如果我想用来tee在控制台上查看 -exec 命令的输出(以查看进度)并附加到文件(供以后使用),则语法是什么?

(我知道 shell 各不相同,但希望最常用的 shell,例如 sh/csh 非常相似?)

更新:

在某种程度上,我想了解嵌套是否find -exec可以在没有脚本的情况下完成,作为一个简单的命令。这是引发 questio 的用例:

  • 外层find:找到所有匹配 DIR_MATCH_TEXT 的子目录DIR1
  • 内部find:对于在外部循环中找到的每个匹配子目录(称为 DIR2),执行命令
    find DIR2 -name "FILE_MATCH_TEXT" -exec sha1 {} \; >> DIR1/DIR2_hashes.txt

目的是创建一组文件,每个匹配的子目录一个,包含对该子目录的某些find -exec操作的输出。

我的意思是,如果/backups包含/jan2017/feb2017,结果将是两个文件在/backups/jan2017_hashes.txt/backups/feb2017_hashes.txt,其中jan2017_hashes.txt包含来自sha1for(比如说)所有 .pdf 文件的输出/backups/jan2017,并feb2017_hashes.txt包含来自sha1所有 .pdf 文件的输出/backups/feb2017

从到目前为止的答复中,我认为外部find必须使用 shell 调用作为-exec?

And*_*ton 6

I/O 重定向和管道是 shell(例如,bash)的功能。查看find命令的源代码(https://www.gnu.org/software/findutils/),该-exec选项派生并直接执行给定的命令,它不会通过任何外壳发送它。鉴于此,在没有帮助的情况下,您不能在参数中包含管道和重定向find

但是,您可以find调用 shell 并让该 shell 依次调用您的命令。通过 shell 运行相同的程序时,您可以访问 shell 公开的 I/O 重定向操作。考虑,例如:

find . -type f -exec bash -c 'ls -l "$1" >> /tmp/result' find-sh {} \;
Run Code Online (Sandbox Code Playgroud)

这将ls -l在由find(shell 在此上下文中将该文件称为$0)找到的每个文件上运行,并将输出重定向到/tmp/result. 请注意,我使用了>>而不是>. 在这里,find 为每个文件调用一个shell,因此>将导致每个结果覆盖前一个结果——您最终将得到一个仅包含最后一个命令的输出的文件。

管道也可以工作,但同样需要注意“每个文件一个 exec”。

find . -type f -exec bash -c 'ls -l "$1" | grep something' find-sh {} \;
Run Code Online (Sandbox Code Playgroud)

综上所述,我并不清楚为什么您要在-exec.

  • 有两件事:1)当你给 bash 一个虚拟参数“find-sh”时,会有点令人困惑,尤其是在没有解释的情况下。考虑省略它,并在 bash 命令中使用“$0”。2) 作为为什么需要这样做的一个例子,考虑一个“find”命令可能有多个条件“-exec”路径,其中只有一个需要管道,或者多个需要不同类型的管道。例如,我有一个查找命令,“mkdir”是找到的所有目录,通过管道从媒体文件输出“mediainfo”,以及“ln -s”剩余文件。 (4认同)