压缩“find”名称模式

压缩“find”名称模式

我在用

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 上运行它。

答案1

正如您(错误地 - 您使用的是 shell 模式)在主题中提到的那样,您应该使用正则表达式:

find . -iregex '.*\.[ch]+'

上面是惰性方法,它也会查找 .ch、.hh 等类似文件(如果存在)。对于精确匹配,您仍然必须枚举您想要的内容,但是使用正则表达式仍然更容易:

find . -regex '.*\.\(c\|C\|cc\|CC\|h\|H\)'

答案2

可移植/标准(POSIX、Unix (SUS) 和 Linux (LSB) 标准)且高效,您可以这样编写:

find . \( -name '*.cc' -o -name '*.CC' -o -name '*.[cChH]' \) \
  -type f -exec grep -n -- "$1" /dev/null {} +

这里最重要的一点是使用+而不是;.否则,您将为每个文件运行一个 grep 命令。

-H选项是 GNU 特定的,但添加/dev/null(确保grep至少查找两个文件)可保证 grep 显示文件名。

您将需要“--”,除非您可以确保它$1永远不会以 开头-

在此处添加-type f,以避免查看非常规文件(如目录),但这意味着它也排除符号链接,您可能希望将其省略。

答案3

可以缩短为这一行:

find -type f -regextype posix-egrep -iregex '.*\.(cc|h|c)$' -exec grep -nHr "$1" {} \;

相关内容