我正在编写一些处理某些文件的bash / zsh脚本。我想为某个类型的每个文件执行一个命令,其中一些命令重叠。当我尝试find -name 'pattern1' -or -name 'pattern2'
时,只使用最后一个模式(不返回匹配pattern1
的文件;只返回与pattern2
匹配的文件。我想要的是匹配pattern1
或pattern2
匹配的文件。
例如,当我尝试以下操作时,这就是我得到的(通知只有./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
。
为什么找不到bar.html
和foo.xml
?我如何匹配多种模式?
答案 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
从左到右读取,参数顺序很重要!
因此,如果您想要指定某些内容,请尊重and
和or
优先级:
find . -name '*.html' -exec echo ">"{} \; -o -name '*.xml' -exec echo "+"{} \;
或
find . -maxdepth 4 \( -name '*.html' -o -name '*.xml' \) -exec echo {} \;
-print0
和xargs
命令。但是,对于大多数情况,您可以使用-print0
命令考虑xargs
,例如:
find . \( -name '*.html' -o -name '*.xml' \) -print0 |
xargs -0 printf -- "-- %s -\n"
这样做的好处是:
找到了数千个条目,只有一个(或几个) fork 。 (使用-exec echo {} \;
表示为找到每个条目运行一个子进程,而xargs
将使用一个命令行可以容纳的参数构建一个长行...)< / p>
为了处理包含特殊字符或空格的文件名,-print0
和xargs -0
将使用 NULL
字符作为文件名分隔符。
从几年前开始,find
命令接受-exec
切换的新语法。
而不是\;
,-exec
切换可以以加号+
结束。
find . \( -name '*.html' -o -name '*.xml' \) -exec printf -- "-- %s -\n" {} +
使用这种语法,find
将像xargs
命令一样工作,构建用于减少分支的长命令行。