Linux find -name "*.xyz" -o -name "*.abc" -exec 对所有找到的文件执行,而不仅仅是指定的最后一个后缀

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8887972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:06:15  来源:igfitidea点击:

find -name "*.xyz" -o -name "*.abc" -exec to Execute on all found files, not just the last suffix specified

linuxbashshellscripting

提问by atxdba

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.

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

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

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

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

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

采纳答案by Dan Fego

findworks 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.

find通过评估您给它的表达式,直到它可以确定整个表达式的真值(真或假)。在您的情况下,您实际上是在执行以下操作,因为默认情况下它将表达式 AND 在一起。

-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.

GNU find 搜索以每个给定文件名为根的目录树,通过从左到右评估给定的表达式,根据优先级规则(请参阅操作员部分),直到结果已知(左侧为假和操作, true for or),此时 find 移动到下一个文件名。

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

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

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:

你想要做的是强制优先级,你可以用括号来做。令人讨厌的是,您还需要使用反斜杠在 shell 上对它们进行转义:

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

回答by Rob Wouters

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

回答by user unknown

More usable than Jaypal's solution would maybe be:

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

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

回答by chemila

It may work:

它可能有效:

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