在find命令中使用正则表达式以查找多个文件类型

6
我目前正在使用
find . -name '*.[cCHh][cC]' -exec grep -nHr "$1" {} ; \
find . -name '*.[cCHh]' -exec grep -nHr "$1" {} ;

在所有子目录中搜索以.c、.C、.h、.H、.cc和.CC结尾的文件中的字符串。但由于这包含了两个命令,因此感觉效率低下。
我该如何使用一个单一的正则表达式模式来查找.c、.C、.h、.H、.cc和.CC文件?
我正在使用Linux机器上的bash。

2
顺便提一下,-name 命令参数中的参数不是一个正则表达式,而是一个 shell 扩展。 - rid
4个回答

16

你可以使用布尔“OR”参数:

find . -name '*.[ch]' -o -name '*.[CH]' -o -name '*.cc' -o -name '*.CC'

以上代码搜索当前目录及所有子目录中以以下文件结尾的文件:

  • .c, .h
  • .C, .H
  • .cc
  • .CC

3
比起仅用正则表达式来完成所有操作,这种方法更加优雅。 - Donal Fellows
如果你想添加"-exec",这个方法就不起作用了。例如:"find -name *.log' -o -name *.txt -exec cat '{}' ; " 它只会执行第一个"-name"。 - OutputLogic
如果由于某种原因你没有意识到,那么-o是用来表示的。 - Crowie
5
@OutputLogic 使用 find 的优先级运算符 ( 和 ) 来解决这个问题,例如 find \( -name "*.log" -o -name "*.txt" \) -exec cat {} \; 应该能够按预期工作。 - Peter Briggs
1
Rid - 你介意更新一下你的回答,这样普通读者就不会错过Briggs的观点了吗? - John

12

这应该可以运行

混乱的

find . -iregex '.*\.\(c\|cc\|h\)' -exec grep -nHr "$1" {} +

-iregex用于匹配不区分大小写的正则表达式模式。

(c|cc|h)(未显示恶意转义字符)匹配扩展名为c、cc或h。


Clean

find -regextype "posix-extended" -iregex '.*\.(c|cc|h)' -exec grep -nHr "$1" {} +

这也会找到扩展名为.Cc和.cC的文件。警告你了。


2
这个命令有效。
find -regextype posix-extended -regex '.+\.(h|H|c{1,2}|C{1,2})$'

我希望能使用iregex。如果使用iregex,也可以找到.Cc.cC。如果可以的话,命令会像这样。只是稍微短一点。

find -regextype posix-extended -iregex '.+\.(h|H|c{1,2})$'

0

find . -regex '.*\.\([chCH]\|cc\|CC\)'
将会查找所有以.c、.C、.h、.H、.cc 和 .CC 结尾的文件,并且不会查找任何以.hc、.cC 或 .Cc 结尾的文件。在正则表达式中,前几个字符匹配名称中的最后一个句点, 圆括号内的备选项匹配 c、h、C 或 H 中的任意单个字符,或者匹配 cc 或 CC。

注意,find 命令的 -regex-iregex 开关类似于 -name-iname,但是正则表达式类型的开关允许使用 | 来进行备选匹配。与 -iname 一样,-iregex 不区分大小写。

前一个答案中给出的(非功能性)形式
find . -name '*.[cCHh][cC]?$'
在我的GNU find 4.4.2 Linux系统上没有列出任何名称。 作为正则表达式,'*.[cCHh][cC]?$' 的另一个问题是它将匹配像abc.Cc和xyz.hc这样的名称,而这些名称并不属于你想要的.c、.C、.h、.H、.cc和.CC文件集合。


第一种形式不起作用是因为 ?$ 不是 shell 模式,所以它们被按字面意义解释。 - doubleDown
@rid,我编辑了一下,指出-iregex '.*\.[ch]\|.*\.cc'不匹配.cH。然而,我同意它匹配.Cc和.cC,并添加了一个精确扩展名集的正则表达式。 - James Waldby - jwpat7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接