用-execdir查找


16

当我find和我一起跑步时,-execdir没有得到预期的结果。

例如:

mkdir -p a/b/c
find . -type d -execdir touch foo \;
$ tree a
a
├── b
   ├── c
   └── foo
└── foo

目录c不包含foo文件。如何find在每个目录中本地访问和执行某些操作?

Answers:


18

对于每个匹配文件(即每个目录),find切换到包含该文件的目录(即其父目录)并执行指定的命令。由于该命令不使用匹配项的名称,因此它永远不会作用于所有目录。对于这个特定的目录树,您正在做

(cd . && touch foo)        # because ./a matches
(cd ./a && touch foo)      # because ./a/b matches
(cd ./a/b && touch foo)    # because ./a/b/c matches

要在每个目录中创建文件,您可以简单地使用-exec代替-execdir,只要您在参数中实现了findallow 的实现{}(大多数情况下,尤其是我认为的所有情况):

find . -type d -exec touch {}/foo +

为了实现POSIX的可移植性,您需要手动组装目录名称和文件库名称。

find . -type d -exec sh -c 'touch "$0/foo"' {} \;

或(快一点)

find . -type d -exec sh -c 'for d; do touch "$d/foo"; done' _ {} +

另外,您可以使用bash的递归通配符匹配。请注意(与ksh和zsh中的相应功能不同,并且与您的find命令不同),bash在指向目录的符号链接下递归。

shopt -s globstar
for d in **/*/; do touch -- "$d/foo"; done

一个zsh解决方案:

touch ./**/(e\''REPLY+=foo'\')

仅供参考:man bash“-c”下的状态:command_string之后的参数分配给以$ 0开头的位置参数,但是“ for d”将迭代以$ 1开头的位置参数。“ _”是分配给$ 0的文本,将不使用。
乍得斯基特斯,2016年

3

该命令在包含匹配文件的每个目录中执行。以来c不包含目录,因此它不匹配,因此不会在该目录中运行。

解决方案是将目录名称添加到execdir参数,如下所示:

find . -type d -execdir touch {}/foo \;

2

man file

   -execdir command {} +
          Like  -exec,  but  the  specified  command is run from the subdirectory containing the matched file

您匹配的目录c位于该b目录中,因此是运行exec的位置。如果要查找文件而不是目录,它将按预期工作。

您可以通过将目录发送到来实现所需的功能,xargs因为目录将提供完整目录列表。

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.