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


334

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

然后是手册页:

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

由于这是管道链的一部分,因此我希望能够指定它在运行时匹配的扩展名(无需硬编码)。如果find不能做到这一点,则可以使用perl单线(或类似格式)。

编辑:我最终想出的答案包括各种废话,而且有点长,所以我将其发布为我试图抓痒的原始痒的答案。如果您有更好的解决方案,请随意修改。



locate尽管内部的更新b可能不是最新的警告,但也是经常被忽视和使用不足的实用程序。但是很快。
迈克尔

我投票结束这个问题是因为题外,因为它属于Unix&Linux
Dan Dascalescu,

Answers:


480

使用-o,表示“或”:

find Documents \( -name "*.py" -o -name "*.html" \)

您需要以编程方式构建该命令行,这并不容易。

您是否正在使用bash(或Windows上的Cygwin)?如果是这样,您应该可以执行以下操作:

ls **/*.py **/*.html

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


3
我使用的是zsh,一般来说,它支持所有bashisms以及更多。
熊加米奥夫09年

12
Zsh支持**递归搜索;Bash仅在4.0及更高版本中支持它,并且仅在上支持shopt -s globstar
短暂

2
您可以有几个-o args?我有大量潜在的.gcda(覆盖数据)文件要建立
Jasper Blues

40
-name如果使用,则需要用括号将两个括起来-exec。EGfind Documents \( -name "*.py" -o -name "*.html" \) -exec file {} \;
artbristol

2
@artbristol注释非常有用,例如,如果要添加一个-print0用于处理带空格的文件名。
nimrodm

63

find的某些版本(主要在linux系统上)可能还会在其他版本上支持-regex和-regextype选项,这些选项可查找名称与regex匹配的文件。

例如

find . -regextype posix-egrep -regex ".*\.(py|html)$" 

应该在上面的示例中做到这一点。但是,这不是标准的POSIX查找功能,并且取决于实现。


1
有趣

12
更简单:find . -regex ".*\.\(py\|html\)$"之所以可行,是因为find缺省为Emacs样式的正则表达式,它们略有不同,因此您不必指定regextype。
robru

2
如果您有很多表达-regextype posix-egrep方式很方便(否则,您需要转义许多字符)。这是我用于构建Windows发行版zip的dist-hook的find命令(查找要更改的文件,并在文件中将其更改为dos-eol): find -regextype posix-egrep -regex ".*(\.([chyl]|def|cpy|cob|conf|cfg)|(README|ChangeLog|AUTHORS|ABOUT-NLS|NEWS|THANKS|TODO|COPYING.*))$" -exec sed -i -e 's/\r*$/\r/' {} \;
Simon Sobisch

32

您可以通过编程方式添加更多的-name子句,并用-or

find Documents \( -name "*.py" -or -name "*.html" \)

或者,改为进行简单循环:

for F in Documents/*.{py,html}; do ...something with each '$F'... ; done

@ user2284570:那么要么没有*.py文件,要么您有奇特的版本find。上面列出的命令可以正常工作。
Stephan202

不,我正在使用-iname*.py仅在最后一个位置iname *.html第一个表达式)写入文件时,它才返回文件。我在Debian上使用命令。
user2284570

您在使用引号吗?那很重要
Stephan202

1
是-还是-o?
Stephane 2014年

1
@StephaneEybert:两种都可以,但是只有后者符合POSIX要求(根据手册页)。
Stephan202 2014年

16

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

$ find . -name "*.c" -o -name "*.cpp"

除非您正在执行其他附加操作,否则不需要括号即可。他们在手册页上说的是图案是否匹配,请打印出来。也许他们正在尝试控制打印。在这种情况下,-print充当条件,并成为“与”条件。这将防止打印任何.c文件。

$ find .  -name "*.c" -o -name "*.cpp"  -print

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

$ find . \( -name "*.c" -o -name "*.cpp" \) -print

所有c / c ++源文件的最后一个示例

$ find . \( -name "*.c" -o -name "*.cpp"  -o -name "*.h" -o -name "*.hpp" \) -print

11

我也有类似的需求。这为我工作:

find ../../ \( -iname 'tmp' -o -iname 'vendor' \) -prune -o \( -iname '*.*rb' -o -iname '*.rjs' \) -print

3
完善。但我感到奇怪的是,如果没有()
pedrofurla,2014年

我想查找与* .c * .cpp或* .cc匹配的文件,只有两个-name模式,我不需要parens,但是三个-name模式,加上两个-o模式,find -name "*.cpp" -o -name "*.c" -o -name "*.cc" -print0我不得不使用一对parens将第二个或运算符分组。find -name "*.cpp" -o \( -name "*.c" -o -name "*.cc" \) -print0可能始终为“ true”的-print0影响了逻辑。
cardiff space man's

5

我的默认值是:

find -type f | egrep -i "*.java|*.css|*.cs|*.sql"

就像find布伦丹·朗(Brendan Long)和史蒂芬·202(Stephan202)等人那样,对过程的要求较少的执行是:

find Documents \( -name "*.py" -or -name "*.html" \)


3
这不是对egrepregexp 的正确使用,相反,您有一个应使用regexp的shell glob。(此外,典型find用法是:find {directory} [options...] [action],其中,根据impl的不同,directory可能默认为.action默认为-print,但我将是明确的。)因此,请使用类似的方法:find . -type f -print | egrep -i '\.java$|\.css$|\.cs$|\.sql$' 但是,作为的真正快速替代品findlocate以类似的方式尝试(尽管不一定是最新的,因为它查询内部db以获取文件列表)
michael

2
#! /bin/bash
filetypes="*.py *.xml"
for type in $filetypes
do
find Documents -name "$type"
done

简单但有效:)


1

除了某些文件,我需要删除子目录中的所有文件。以下为我工作(指定了三种模式):

find . -depth -type f -not -name *.itp -and -not -name *ane.gro -and -not -name *.top -exec rm '{}' +

1

\(\)名称模式必须在模式中使用大括号or

find Documents -type f \( -name "*.py" -or -name "*.html" \)

对于带有and运算符的名称模式,则不需要

find Documents -type f ! -name "*.py" -and ! -name "*.html" 

0

这适用于AIX korn shell。

find *.cbl *.dms -prune -type f -mtime -1

这仅在当前目录中查找*.cbl*.dms已使用1天,因此会跳过子目录。


0
find MyDir -iname "*.[j][p][g]"
+
find MyDir -iname "*.[b][m][p]"
=
find MyDir -iname "*.[jb][pm][gp]"

2
请注意,后者将匹配foo.jmg,但前两个都不匹配。
copper.hat

0

关于什么

ls {*.py,*.html}

它列出了所有以.py或.html结尾的文件名

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.