Macos 为什么';找不到让我匹配多个模式?

Macos 为什么';找不到让我匹配多个模式?,macos,bash,shell,unix,zsh,Macos,Bash,Shell,Unix,Zsh,我正在编写一些bash/zsh脚本来处理一些文件。我想为特定类型的每个文件执行一个命令,其中一些命令重叠。当我尝试查找-name'pattern1'-或-name'pattern2'时,只使用最后一个模式(不返回与pattern1匹配的文件;只返回与pattern2匹配的文件)。我想要的是匹配pattern1或pattern2的文件被匹配 例如,当我尝试以下操作时,我得到的结果是(请注意,只找到并打印了/foo.xml): 使用-o而不是-or会得到相同的结果。如果我切换-name参数的顺序,则

我正在编写一些bash/zsh脚本来处理一些文件。我想为特定类型的每个文件执行一个命令,其中一些命令重叠。当我尝试
查找-name'pattern1'-或-name'pattern2'
时,只使用最后一个模式(不返回与
pattern1
匹配的文件;只返回与
pattern2
匹配的文件)。我想要的是匹配
pattern1
pattern2
的文件被匹配

例如,当我尝试以下操作时,我得到的结果是(请注意,只找到并打印了
/foo.xml
):

使用
-o
而不是
-or
会得到相同的结果。如果我切换
-name
参数的顺序,则只返回
bar.html
,而不返回
foo.xml


为什么没有找到并返回
bar.html
foo.xml
?如何匹配多个模式?

您需要在
find
命令中使用括号对您的条件进行分组,否则只有第二个
-name
选项对
-exec
命令有效

find . \( -name '*.html' -or -name '*.xml' \) -exec echo {} \;
查找实用程序
-打印
==默认值 如果只想打印文件路径和名称,则必须删除
exec echo
,因为
-print
是默认设置:

find . -name '*.html' -or -name '*.xml'
顺序依赖 否则,
find
从左到右读取,参数顺序很重要

因此,如果要指定某个内容,请遵守
以及
优先级:

find . -name '*.html' -exec echo ">"{} \;  -o -name '*.xml' -exec echo "+"{} \;

表达式
-print0
xargs
命令。 <>但是,对于大多数情况,您可以考虑<代码> -PROT00/COD>使用<代码> XARGS命令,如:

find . \( -name '*.html' -o -name '*.xml' \) -print0 |
    xargs -0 printf -- "-- %s -\n"
这样做的好处是:

  • 只有一个(或几个)叉子可以容纳数千个条目。(使用
    -exec echo{}\
    意味着为找到的每个条目运行一个子进程,而
    xargs
    将构建一条长行,其中包含一个命令行可以容纳的尽可能多的参数…)

  • 为了处理包含特殊字符或空白的文件名,
    -print0
    xargs-0
    将使用
    NULL
    字符作为文件名分隔符

找到-执行。。。{} ... + 从几年前开始,
find
命令接受
-exec
开关的新语法

而不是
\
-exec
开关可以以加号
+
结束

find . \( -name '*.html' -o -name '*.xml' \) -exec printf -- "-- %s -\n" {} +

使用这种语法,
find
将像
xargs
命令一样工作,构建长的命令行以减少分叉。

很酷,我没有意识到可以将它们分组到不同的执行组中(即
find.-name'pattern1'-execcmd1\;-o-name'pattern2'-execcmd2\;
(省略
-o
只会导致使用和执行第一个“组”)。是的,确实有两个不同的
-exec
也是可能的。除了使用
-print0
xargs
,您还可以通过使用
-exec COMMAND{}+
而不是
-exec COMMAND{}来减少分叉的数量;
,即使用
+
而不是
\
终止
-exec
。因此
查找。\-name'*.html'-o-name'*.xml'\)-exec printf'\-%s-\n{}+
应以较少的键入量执行相同的操作。(还要注意
`before
-->这是必需的,至少在我的系统上是如此,以防止
printf
将整个引用的模式解释为命令行参数)。嗯,这是一个有趣的新选项,谢谢@Adaephon。但我怀疑这个选项可能不存在于某些不同的find实现中…@Adaephon:Good point re
-exec…+
;在操作数(非选项)中重新解释
--
(或
--
):处理此问题的可移植方法是在操作数之前使用特殊选项
--
,以明确表示后面的是操作数,而不是选项:
printf--“--%s-n\n”{}
-exec+符合POSIX标准;参见,因此优于非标准的
-print0
操作;另外
-exec+
需要更少的输入,它也比
-print0
/
xargs
组合更高效。
find . \( -name '*.html' -o -name '*.xml' \) -print0 |
    xargs -0 printf -- "-- %s -\n"
find . \( -name '*.html' -o -name '*.xml' \) -exec printf -- "-- %s -\n" {} +