查找-名称“*.xyz” -o -名称“*.abc” -exec 对所有找到的文件执行,而不仅仅是指定的最后一个后缀

发布于 2024-12-27 11:47:39 字数 294 浏览 1 评论 0原文

我正在尝试运行

find ./ -name "*.xyz" -o -name "*.abc" -exec cp {} /path/i/want/to/copy/to

事实上,它是一个更大的扩展名列表,但我不知道这对于这个例子来说很重要。基本上我想将所有找到的内容复制到另一个/path/i/want/to/copy/to。然而,它似乎只执行列表中的姓氏测试。

如果我删除 -exec 部分,我期望找到的所有文件变体都会打印出来。

如何让它将找到的完整文件传递给 -exec?

I'm trying to run

find ./ -name "*.xyz" -o -name "*.abc" -exec cp {} /path/i/want/to/copy/to

In reality it's a larger list of name extensions but I don't know that matters for this example. Basically I'd like to copy all those found to another /path/i/want/to/copy/to. However it seems to only be executing the last -name test in the list.

If I remove the -exec portion all the variations of files I expect to be found are printed out.

How do I get it to pass the full complement of files found to -exec?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

饭团 2025-01-03 11:47:39

find 的工作原理是评估您提供的表达式,直到它可以确定整个表达式的真值(true 或 false)。在您的情况下,您实际上是在执行以下操作,因为默认情况下它将表达式与在一起。

-name "*.xyz" OR ( -name "*.abc" AND -exec ... )

引用手册页:

GNU 查找搜索
通过评估以每个给定文件名为根的目录树
根据优先级规则(参见运算符部分)从左到右给定表达式,直到知道结果(左边
手边对于 and 运算为假,对于 or) 为真,此时
find 移动到下一个文件名。

这意味着如果名称与 *.xyz 匹配,它甚至不会尝试检查后面的 -name 测试或 -exec,因为这已经是事实了。

您想要做的是强制优先级,您可以使用括号来做到这一点。烦人的是,您还需要使用反斜杠在 shell 上转义它们:

find ./ \( -name "*.xyz" -o -name "*.abc" \) -exec cp {} /path/i/want/to/copy/to \;

find works by evaluating the expressions you give it until it can determine the truth value (true or false) of the entire expression. In your case, you're essentially doing the following, since by default it ANDs the expressions together.

-name "*.xyz" OR ( -name "*.abc" AND -exec ... )

Quoth the man page:

GNU find searches
the directory tree rooted at each given file name by evaluating the
given expression from left to right, according to the rules of precedence (see section OPERATORS), until the outcome is known (the left
hand side is false for and operations, true for or), at which point
find moves on to the next file name.

That means that if the name matches *.xyz, it won't even try to check the latter -name test or -exec, since it's already true.

What you want to do is enforce precedence, which you can do with parentheses. Annoyingly, you also need to use backslashes to escape them on the shell:

find ./ \( -name "*.xyz" -o -name "*.abc" \) -exec cp {} /path/i/want/to/copy/to \;
混吃等死 2025-01-03 11:47:39

比 Jaypal 的解决方案更有用的可能是:

   find ./ -regex ".*\.\(jpg\|png\)" -exec cp {} /path/to

More usable than Jaypal's solution would maybe be:

   find ./ -regex ".*\.\(jpg\|png\)" -exec cp {} /path/to
小苏打饼 2025-01-03 11:47:39
find . \( -name "*.xyz" -o -name "*.abc" \) -exec cp {} /path/i/want/to/copy/to \;
find . \( -name "*.xyz" -o -name "*.abc" \) -exec cp {} /path/i/want/to/copy/to \;
喵星人汪星人 2025-01-03 11:47:39

它可能有效:

find ./ -name "*.{xyz,abc}" -exec cp {} /path/i/want/to/copy/to

It may work:

find ./ -name "*.{xyz,abc}" -exec cp {} /path/i/want/to/copy/to
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文