使用 -execdir 查找

Mar*_*tus 18 shell directory find directory-structure files

当我运行时find-execdir我没有得到我期望的结果。

例如:

mkdir -p a/b/c
find . -type d -execdir touch foo \;
$ tree a
a
??? b
?   ??? c
?   ??? foo
??? foo
Run Code Online (Sandbox Code Playgroud)

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

Gil*_*il' 19

对于每个匹配的文件(即每个目录),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
Run Code Online (Sandbox Code Playgroud)

要在每个目录中创建一个文件,您可以简单地使用-exec代替-execdir,前提是您在参数中实现了find允许{}(大多数都这样做,特别是我认为所有的):

find . -type d -exec touch {}/foo +
Run Code Online (Sandbox Code Playgroud)

对于 POSIX 可移植性,您需要手动组装目录名和文件基名。

find . -type d -exec sh -c 'touch "$0/foo"' {} \;
Run Code Online (Sandbox Code Playgroud)

或(稍快)

find . -type d -exec sh -c 'for d; do touch "$d/foo"; done' _ {} +
Run Code Online (Sandbox Code Playgroud)

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

shopt -s globstar
for d in **/*/; do touch -- "$d/foo"; done
Run Code Online (Sandbox Code Playgroud)

zsh 解决方案:

touch ./**/(e\''REPLY+=foo'\')
Run Code Online (Sandbox Code Playgroud)


Jen*_*y D 7

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

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

find . -type d -execdir touch {}/foo \;
Run Code Online (Sandbox Code Playgroud)


Mat*_*att 5

man find

\n
\n

-execdir command {} +

    \n与 类似-exec,但指定的命令是从包含匹配文件的子目录运行的...

\n

\n

您的匹配目录c位于b目录中,因此这就是运行 exec 的位置。\xe2\x80\x83 如果您正在查找文件而不是目录,它将按照您的预期工作。

\n

您可以通过将目录发送到来实现您想要的目的xargs,\nas 来实现您想要的目的,\nas 将提供完整的目录列表。

\n