是否可以将“ find -exec”嵌套在另一个“ find -exec”中?


14

我追求的是以下内容,但是无论我如何转义{}+ ;

find ./ -maxdepth 1 -type d -name '.*' -exec \
    find {} -maxdepth 1 -type f -name '*.ini' -exec \
        md5sum \{\} \\; \;

看到Unix-&-Linux问题之后,我发现以下代码可以工作,但它不是嵌套find,因此我怀疑有更好的方法来完成此特定工作。

find ./ -maxdepth 1 -type d -name '.*' \
-exec bash -c 'for x; do
    find "$x" -maxdepth 1 -type f -name "*.ini" \
    -exec md5sum \{\} \;; \
done' _ {} \+

有没有什么方法可以嵌套,find -exec而无需调用外壳(如上),并具有所有引人注目的引用和转义约束?

还是可以使用多个参数的混合,在单个find命令中直接完成此操作?


4
尽管可以按照您的要求进行操作,但是当事情变得如此复杂时,我会切换到Shell或Perl脚本。您的第二个代码段几乎是这样做的,仅使用内联的Shell脚本。英勇的一线好客,但他们很难理解,因此很难维护。除非这是一次单笔交易,但是您最终还是会擅长于此,否则除了智力上的挑战,我看不出有这样做的充分理由。
沃伦·杨

1
@沃伦·杨(Warren Young):我当然不认为这个概念很复杂,但是我想您的意思是,没有简单的方法可以解决这个问题,find但是如果find不能这样做,那为什么会find如此受人尊敬(?)作为工具-可以用来查找文件吗?...我已经成功地找到了适合find ./ -maxdepth 2 -path '.*/*.ini' -type f -exec md5sum {} \+我的情况(jw013的参考将其-prune引导至手册页中),但是我想知道这是否是一种可靠的方法(一般而言)。我从来没有真正使用过find(在不到一年的Linux中)locate做我几乎需要做的所有事情,所以这是未知领域。
Peter.O 2011年

1
-path测试正是我要建议的。有了这个,您应该就能做所有想做的事情(对Ace Of Base协会表示抱歉;))
rozcietrzewiacz 2011年

Answers:


8

我会尝试使用单个查找,如:

find .*/ -maxdepth 1 -type f -name '*.ini' -execdir md5sum {} +

甚至(根本不行find,只是shell出现问题)

md5sum .*/*.ini

尽管缺少-type f检查,所以仅当您没有以结尾的目录/非文件时,它才有效.ini。如果您可以使用

for x in .*/*.ini; do 
    if [ -f "$x" ]; then 
        md5sum "$x"
    fi
done

但是,这将失去仅需要一次md5sum调用的优势。

编辑

对于一般且安全的链接方法find,您可以执行以下操作

find <paths> <args> -print0 | xargs -0 -I{.} find {.} <args for second find> [etc.]

我得到一个错误与-f,然后用另一个错误(F?) -execdir。当我更换-execdir与-exec,和/或也与打印更换的md5sum,我什么也没得到。。
Peter.O

谢谢,作为替代方案...但是我更想使用find...来解决这个问题,我只是想解决这个问题,我在寻找有关find-fu方法的见解。 (也许不比fu更好。)(我不知道,因为我实际上从没使用过),这是我真正想要使用的第一种情况(实际上是用于图像文件),我已经听到很多的-exec功能似乎不如rep(?)暗示...(不过+1代表其他功能)那么强大..但是您的find示例仍然无法正常工作(仍然)
Peter.O 2011年

我收到以下find命令错误:... find: The relative path 〜/ bin'包含在PATH环境变量中,与find的-execdir操作结合使用时不安全。请从$ PATH`中删除该条目...。因此它可能会起作用,但是我必须说我已经尝试摆脱〜/ bin了一段时间了……我将不得不采取更多措施认真地看一看...我不知道它在哪里设置的。将~/bin在我的道路
Peter.O

我认为,find在无法完全使用glob来完成的情况下,最好能意识到的功能,但是由于这种情况很少见,因此我通常不需要太多查找。
2011年

好吧..这是一个有趣且很好的观点(关于使用
glob

2

您最初的问题不需要递归调用find,但是我想那不是重点。

我相信不可能以您想要的方式递归调用find。

以下内容也不是递归地调用find(或嵌套,无论它叫什么),但是您是否不能只获取第一个find的结果集并将其提供给第二个find?这是我本能地做的:

find `find ./ -maxdepth 1 -type d -name '.*'` \
    -maxdepth 1 -type f -name '*.ini' -exec md5sum {} \;

您也可以xargs用于执行第二个查找。

更新:

我想补充一下,因为大多数UNIX实用程序采用几个文件名参数而不是一个,所以通常可以-exec完全避免:

md5sum `find \`find ./ -maxdepth 1 -type d -name '.*'\` -maxdepth 1 -type f -name '*.ini'`

嵌套反引号时,您只需\在内部反斜杠之前添加反斜杠。

如果我们假设md5sum仅使用一个文件名参数,则可以始终将其包装在for循环中:

for f in `find \`find ./ -maxdepth 1 -type d -name '.*'\` -maxdepth 1 -type f -name '*.ini'`
do
    md5sum $f
done

请注意,如果-涉及到以空格开头或包含空格的文件/目录名称,这将变得更加困难。UNIX实用程序不能很好地使用它们。在这种情况下./--需要添加或引号。

显然,原始示例不是一个很好的示例,因为我们可以这样做:

md5sum .*/*.ini

1
您已经很好地了解了这种情况,但是当文件/目录包含空格时,所有显示的find方法都会出错。... md5sum .*/*.ini工作正常...我开始普遍感觉到* Warren Young's *关于事情变得“复杂”的评论find发生在游戏的早期:),但是我认为find条件测试变得更加复杂,但是就嵌套-exec而言,我已经很好地放弃了这个想法,似乎有更简单的方法可以执行..(但是perl对我来说还不是“简单”……)
Peter.O 2011年

0

至少我设法嵌套了2条find命令:

find ~ -maxdepth 1 -type d -name '.*' -execdir \
    find {} -maxdepth 1 -type f -name '*.ini' \;

但是我没有解决从那里调用另一个-exec(dir)的问题。


是的,那正是我的问题:)
Peter.O 2011年

是的,但不是嵌套3不一样不筑巢2. :)
用户未知
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.