【问题标题】:find -name "*.xyz" -o -name "*.abc" -exec to Execute on all found files, not just the last suffix specifiedfind -name "*.xyz" -o -name "*.abc" -exec 对所有找到的文件执行,而不仅仅是指定的最后一个后缀
【发布时间】:2012-02-11 20:44:25
【问题描述】:

我正在尝试运行

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

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

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

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

【问题讨论】:

    标签: linux bash shell scripting


    【解决方案1】:

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

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

    手册页:

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

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

    您要做的是强制执行优先级,您可以使用括号来执行此操作。烦人的是,您还需要在 shell 上使用反斜杠来转义它们:

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

    【讨论】:

    • -exec cp -t dir {} + 可能更高效
    • 我认为你的意思是“反斜杠”
    • 括号前后空格很重要,否则会报错“find: paths must before expression: (-name”
    【解决方案2】:

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

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

    【讨论】:

    • 是的,您的解决方案更好。我会继续删除我的。 +1
    • 更强大的查找用法
    【解决方案3】:
    find . \( -name "*.xyz" -o -name "*.abc" \) -exec cp {} /path/i/want/to/copy/to \;
    

    【讨论】:

    • 您的回答是正确的,但我接受了 Dan Fego,因为您似乎与他的回答时间相关,而且他的信息量更大。
    【解决方案4】:

    它可能会起作用:

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

    【讨论】:

    • 来自man find:大括号并不被认为是特殊的,尽管包括 Bash 在内的一些 shell 在 shell 模式中赋予大括号具有特殊含义。
    猜你喜欢
    • 2014-03-14
    • 2021-03-22
    • 2022-12-10
    • 2021-01-08
    • 2019-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-10
    相关资源
    最近更新 更多