为什么我找不到让我匹配多种模式?

时间:2015-02-04 20:06:04

标签: macos bash shell unix zsh

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

例如,当我尝试以下操作时,这就是我得到的(通知只有./foo.xml被找到并打印出来):

$ ls -a
.        ..       bar.html foo.xml
$ tree .
.
├── bar.html
└── foo.xml

0 directories, 2 files
$ find . -name '*.html' -or -name '*.xml' -exec echo {} \;
./foo.xml
$ type find
find is an alias for noglob find
find is /usr/bin/find

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

Animated version

为什么找不到bar.htmlfoo.xml?我如何匹配多种模式?

2 个答案:

答案 0 :(得分:8)

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

find . \( -name '*.html' -or -name '*.xml' \) -exec echo {} \;

答案 1 :(得分:3)

查找实用程序

-print ==默认

如果您只想打印文件路径和名称,则必须删除exec echo,因为 -print 是默认的。:

find . -name '*.html' -or -name '*.xml'

订单依赖

否则, find从左到右读取,参数顺序很重要!

因此,如果您想要指定某些内容,请尊重andor优先级:

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

find . -maxdepth 4 \( -name '*.html' -o -name '*.xml' \) -exec echo {} \;

表达式-print0xargs命令。

但是,对于大多数情况,您可以使用-print0命令考虑xargs,例如:

find . \( -name '*.html' -o -name '*.xml' \) -print0 |
    xargs -0 printf -- "-- %s -\n"

这样做的好处是:

  • 找到了数千个条目,只有一个(或几个) fork 。 (使用-exec echo {} \;表示为找到每个条目运行一个子进程,而xargs将使用一个命令行可以容纳的参数构建一个长行...)< / p>

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

找到... -exec ... {} ... +

从几年前开始,find命令接受-exec切换的新语法。

而不是\;-exec切换可以以加号+结束。

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

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

相关问题