grep,但仅某些文件扩展名


964

我正在为grep某些目录编写一些脚本,但是这些目录包含各种文件类型。

我想grep只是.h.cpp现在,但也许其他几个人的未来。

到目前为止,我有:

{ grep -r -i CP_Image ~/path1/;

grep -r -i CP_Image ~/path2/;

grep -r -i CP_Image ~/path3/;

grep -r -i CP_Image ~/path4/;

grep -r -i CP_Image ~/path5/;} 

| mailx -s GREP email@domain.com

谁能告诉我我现在如何只添加特定的文件扩展名?


13
试过了grep -r -i CP_Image ~/path1/*.{h,cpp}吗?

8
使用白银搜索器ag -i CP_Image ~/path[1-5] | mailx -s GREP email@domain.com。任务完成。
Johnsyweb


使用egrep(很可能已预先安装在系统上),然后可以使用正则表达式。
Dogweather

8
GNU成员添加-r到其中grep以使其搜索文件时确实搞砸了,因为这打破了UNIX拥有“一件事做得很好”工具的口号。有一个非常好的工具来查找名称非常明显的文件。
Ed Morton 2013年

Answers:


1349

只需使用--include参数,如下所示:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP email@domain.com

那应该做你想要的。

从下面的HoldOffHunger答案中获取解释:

  • grep:命令

  • -r:递归地

  • -i:忽略大小写

  • --include \*.cpp:所有* .cpp:C ++文件(如果文件名中带有星号的目录,请使用\进行转义)

  • ./:从当前目录开始。


123
作为记录:-r(递归)-i(忽略大小写)--include(仅搜索与文件模式匹配的文件)
Luis 2013年

34
可以进一步优化grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345]
zwol

1
@Hong -R用于符号链接的文档在哪里?
titus

8
该示例似乎得分很高,因为它涵盖了如此广泛的可能性,但是下面的grep -r --include = *。txt'searchterm'给出的答案。/确实说明了答案的本质
David Casper

10
为什么不使用双引号而不是反斜杠?例如:grep -r -i --include="*.h" --include="*.cpp" CP_Image
pambda '04

283

其中一些答案似乎语法过于繁重,或者在我的Debian Server上产生了问题。这对我来说非常有效:

PHP Revolution:如何在Linux中仅复制某些文件扩展名的Grep文件?

即:

grep -r --include=\*.txt 'searchterm' ./

...或不区分大小写的版本...

grep -r -i --include=\*.txt 'searchterm' ./
  • grep:命令

  • -r:递归地

  • -i:忽略大小写

  • --include:所有* .txt:文本文件(如果文件名中带有星号的目录,请使用\进行转义)

  • 'searchterm':搜索内容

  • ./:从当前目录开始。


7
您应该转义*使用\*.cpp'*.cpp'。否则,当工作目录包含一些*.txt文件时,它将不会给出预期的结果。
Melebius

@Melebius您可以解释为什么需要转义吗-它与您提到的CPP或TXT扩展有关系吗?还是只是使用这些作为示例?
西蒙·伊斯特

2
@SimonEast这些扩展名是在本问答中使用的扩展名,否则没有什么特别的。使用时它可能会在不逃避的情况下工作,--include=<pattern>但重要的是要*使用--include <pattern>(以空格代替=)进行转义,否则感觉会非常相似。
Melebius

52
grep -rnw "some thing to grep" --include=*.{module,inc,php,js,css,html,htm} ./

3
grep -rn“有些东西要grep” --include = *。{module,inc,c,h} *
ashish 2015年

3
好答案。比国际海事组织(IMO)接受的清洁,但您应添加搜索条件,如@ashish所示
billynoah

为什么一个接一个的--include选择,而不是其他选择?
vladkras

@vladkras,针是什么意思?是--
heretoinfinity

50

怎么样:

find . -name '*.h' -o -name '*.cpp' -exec grep "CP_Image" {} \; -print

5
我建议对这些-name论点进行分组。如果不这样做,可能会发生奇怪的事情。find . \( -name '*.h' -o -name '*.cpp' \) -exec grep "CP_Image" {} \; -print
nullrevolution 2012年

与其他“ -f型”一起使用时,将忽略仅对文件感兴趣的所有目录对象。
肯赛

1
我使用这种方法已经好多年了,但是它比递归grep慢了很多,因为find的exec为要搜索的每个文件生成了一个单独的grep进程。
beaudet

处理@beaudet的注释,find可以有选择地捆绑参数,从而将对被调用进程的调用减至最少。 find . \( -name \*.h -o -name \*.cpp \) -exec grep -H CP_Image {} + 这是建议的,但在下面@fedorqui的答案中未突出显示,这是值得改进的地方。在-H当发现只有确定一个匹配的文件在这里grep的说法是有用的。这可以消除-print答案中的用法。如果您的文件总数足够小,则最好使用递归Shell Glob(例如{path1,path2}/**/*.{cpp,h})。
马尔科姆

19

HP和Sun服务器上没有-r选项,这种方式对我的HP服务器有效

find . -name "*.c" | xargs grep -i "my great text"

-i用于不区分大小写的字符串搜索


1
我遇到了几台针对Web托管公司的服务器,这些服务器没有fgrep可用的--include选项,这是我在这些实例中使用的命令行。
Borgboy

当在Windows上使用Git(MinGW / MSys)时,--include选项也不可用。
达伦·刘易斯

@DarrenLewis在Windows的Git Bash中可用。但是奇怪的是,它添加了五颜六色的别名,例如ll但不添加--color=auto到grep。
Xeverous

这应该是完整性,可移植性和简洁性的公认答案!
Grant Foster

12

由于这只是查找文件的问题,因此我们使用find吧!

使用GNU find,您可以使用该-regex选项在目录树中查找扩展名为.h或的那些文件.cpp

find -type f -regex ".*\.\(h\|cpp\)"
#            ^^^^^^^^^^^^^^^^^^^^^^^

然后,只需执行grep每个结果即可:

find -type f -regex ".*\.\(h\|cpp\)" -exec grep "your pattern" {} +

如果您没有find的这种分布,则必须使用Amir Afghani的方法(-o用于连接选项)(名称以.h或结尾.cpp):

find -type f \( -name '*.h' -o -name '*.cpp' \) -exec grep "your pattern" {} +
#            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

如果您真的想使用grep,请遵循指示的语法--include

grep "your pattern" -r --include=*.{cpp,h}
#                      ^^^^^^^^^^^^^^^^^^^

7

最简单的方法是

find . -type  f -name '*.extension' | xargs grep -i string 

3

ag (白银搜索者)对此具有非常简单的语法

       -G --file-search-regex PATTERN
          Only search files whose names match PATTERN.

所以

ag -G *.h -G *.cpp CP_Image <path>

使用ag 2.2.0,我需要把我的旗帜放在最后:ag _string_to_find_ -G _filename_regex_
ryanrain

3

下面的答案是好的:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP email@domain.com

但可以更新为:

grep -r -i --include \*.{h,cpp} CP_Image ~/path[12345] | mailx -s GREP email@domain.com

哪个更简单。


1

应该为每个“ -o -name”写“ -exec grep”

find . -name '*.h' -exec grep -Hn "CP_Image" {} \; -o -name '*.cpp' -exec grep -Hn "CP_Image" {} \;

或按()分组

find . \( -name '*.h' -o -name '*.cpp' \) -exec grep -Hn "CP_Image" {} \;

选项“ -Hn”显示文件名和行。


1

我知道这个问题有些陈旧,但是我想分享一下我通常用于查找.c.h文件的方法:

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -H "#include"

或者,如果您还需要行号:

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -nH "#include"
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.