`find -name`模式匹配多个模式

Xio*_*iov 308 shell find

我试图用命令获取目录中所有python和html文件的列表find Documents -name "*.{py,html}".

然后是手册页:

模式('{}')中的大括号不被认为是特殊的(即,find.-name'foo {1,2}'匹配名为foo {1,2}的文件,而不是文件foo1和foo2.

由于这是管道链的一部分,我希望能够在运行时指定它匹配的扩展名(没有硬编码).如果找不到它,perl单行(或类似)就可以了.

编辑:我最终提出的答案包括各种各样的废话,并且有点长,所以我发布它作为我试图划伤的原始痒的答案.如果你有更好的解决方案,请随意破解.

Ric*_*dle 445

使用-o,表示"或":

find Documents \( -name "*.py" -o -name "*.html" \)
Run Code Online (Sandbox Code Playgroud)

编辑:对不起,只需重新阅读问题...您需要以编程方式构建该命令行,这并不容易.

您使用的是bash(或Windows上的Cygwin)吗?如果你是,你应该能够这样做:

ls **/*.py **/*.html
Run Code Online (Sandbox Code Playgroud)

这可能更容易以编程方式构建.

编辑:应用@artbristol评论答案.

  • 如果你使用`-exec`,你需要用括号括起两个`-name`s.例如`find Documents \( - name"*.py"-o -name"*.html"\) - exec file {} \;` (38认同)
  • Zsh支持`**`进行递归搜索; Bash仅在版本4.0及更高版本中支持它,并且仅支持`shopt -s globstar`. (10认同)
  • 我正在使用zsh,作为一般规则,它支持所有的bashisms,以及更多. (3认同)
  • 你有几个-o args?我有一个可能很大的.gcda(覆盖数据)文件列表要构建 (2认同)
  • 例如,如果要添加`-print0`来处理带空格的文件名,@ artbristol注释非常相关. (2认同)

小智 57

一些版本的find,主要是在linux系统上,可能在其他版本上也支持-regex和-regextype选项,它们查找名称与正则表达式匹配的文件.

例如

find . -regextype posix-egrep -regex ".*\.(py|html)$" 
Run Code Online (Sandbox Code Playgroud)

应该在上面的例子中做到这一点.但是,这不是标准的POSIX查找功能,而是依赖于实现.

  • 更简单:`找到.-regex".*\.\(py\| html \)$"`这是有效的,因为查找默认为Emacs样式的正则表达式,略有不同,因此您不必指定正则表达式. (11认同)
  • 如果您有很多表达式,`-regextype posix-egrep`很方便(否则您需要转义许多字符)。这是我用于构建Windows发行版zip的dist-hook的find命令(查找要更改的文件,并在文件中将其更改为dos-eol):`find -regextype posix-egrep -regex“。*( \。([chyl] | def | cpy | cob | conf | cfg)|(自述文件| ChangeLog |作者| ABOUT-NLS |新闻|谢谢| TODO | COPYING。*))“” -exec sed -i -e' s / \ r * $ / \ r /'{} \;` (2认同)

Ste*_*202 30

您可以通过编程方式添加更多-name子句,分隔符为-or:

find Documents \( -name "*.py" -or -name "*.html" \)
Run Code Online (Sandbox Code Playgroud)

或者,转而使用简单的循环:

for F in Documents/*.{py,html}; do ...something with each '$F'... ; done
Run Code Online (Sandbox Code Playgroud)

  • 是 -or 还是 -o ? (2认同)
  • @StephaneEybert:两者都可以,但只有后者符合 POSIX 标准(根据手册页)。 (2认同)

bki*_*idd 11

我有类似的需求.这对我有用:

find ../../ \( -iname 'tmp' -o -iname 'vendor' \) -prune -o \( -iname '*.*rb' -o -iname '*.rjs' \) -print
Run Code Online (Sandbox Code Playgroud)

  • 完善.但我觉得有点奇怪,没有`()`它就行不通 (3认同)

net*_*ink 10

这将在linux上找到所有.c或.cpp文件

$ find . -name "*.c" -o -name "*.cpp"
Run Code Online (Sandbox Code Playgroud)

除非你正在做一些额外的mod,否则你不需要转义的括号.在手册页中,他们说如果模式匹配,则打印出来.也许他们正试图控制印刷.在这种情况下,-print充当条件并成为"AND'd"条件.它将阻止打印任何.c文件.

$ find .  -name "*.c" -o -name "*.cpp"  -print
Run Code Online (Sandbox Code Playgroud)

但如果您喜欢原始答案,则可以控制打印.这将找到所有.c文件.

$ find . \( -name "*.c" -o -name "*.cpp" \) -print
Run Code Online (Sandbox Code Playgroud)