如何找出当前目录中不包含单词foo(使用grep)的文件?


当前回答

下面的命令给出了所有不包含foo模式的文件:

find .  -not  -ipath '.*svn*' -exec  grep  -H -E -o -c  "foo"  {} \; | grep 0

其他回答

打开错误报告

正如@tukan所评论的,Ag有一个关于-L/——files-without-matches标志的开放错误报告:

Ggreer /the_silver_searcher: #238 -——files-without-matches不能正常工作

由于bug报告几乎没有进展,所以不应该依赖下面提到的-L选项,只要bug还没有解决。请使用本文中介绍的不同方法。引用bug报告的注释[强调我的]:

有最新进展吗?-L完全忽略文件第一行的匹配项。似乎如果这个问题不会很快得到解决,这个标志应该被完全移除,因为它根本不像宣传的那样有效。


Silver Searcher - Ag(预期功能-见错误报告)

作为grep的强大替代品,您可以使用the Silver Searcher - Ag:

一个类似于ack的代码搜索工具,专注于速度。

查看man ag,我们找到了-L或——files-without-matches选项:

... 选项 ... - l - files-without-matches 只打印不包含匹配项的文件名。

也就是说,从当前目录中递归搜索不匹配foo的文件:

ag -L foo

要只搜索当前目录中不匹配foo的文件,只需为递归指定——depth=0:

ag -L foo --depth 0

当您使用find时,您有两个基本选项:在find完成搜索后过滤结果,或者使用一些内置选项来阻止find考虑那些匹配某些给定模式的文件和dirs。

如果您在大量的文件和dirs上使用前一种方法。您将使用大量的CPU和RAM来将结果传递给第二个进程,而第二个进程反过来也会使用大量的资源来过滤结果。

如果你使用-not关键字作为一个find参数,你将阻止任何与后面的name或-regex参数上的字符串匹配的路径被考虑,这将更有效。

find . -not -regex ".*/foo/.*" -regex ".*"

然后,任何没有被-not过滤掉的路径都将被后续的-regex参数捕获。

如果你正在使用git,它会搜索所有被跟踪的文件:

git grep -L "foo"

如果你打开了**子目录globbing,你可以在跟踪文件的子集中搜索(在.bashrc中使用shopt -s globstar):

git grep -L "foo" -- **/*.cpp

下面的命令给出了所有不包含foo模式的文件:

find .  -not  -ipath '.*svn*' -exec  grep  -H -E -o -c  "foo"  {} \; | grep 0

问题

我需要重构一个使用.phtml文件编写HTML使用内联PHP代码的大型项目。我想用胡子模板代替。我想找到任何。phtml贾尔斯不包含字符串新的胡子,因为这些仍然需要重写。

解决方案

找到。- iname”*。phtml' -exec grep -H -E -o -c '新胡子' {}\;| grep:0$ | sed 's/..$//'

解释

在管道之前:

Find

找到。递归地查找文件,从这个目录开始

- iname”*。文件名必须包含.phtml (i使其不区分大小写)

-exec 'grep -H -E -o -c 'new Mustache'{}'在每个匹配的路径上执行grep命令

Grep

始终用输出行打印文件名标题。

将pattern解释为扩展的正则表达式(即force grep 表现得像egrep)。

-o只打印匹配的行。

-c只将选定的行数写入标准输出。


这将给我一个以.phtml结尾的所有文件路径的列表,并计算字符串new Mustache在每个路径中出现的次数。

$> find . -iname '*.phtml$' -exec 'grep -H -E -o -c 'new Mustache' {}'\;

./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml:0
./app/MyApp/Customer/View/Account/studio.phtml:0
./app/MyApp/Customer/View/Account/orders.phtml:1
./app/MyApp/Customer/View/Account/banking.phtml:1
./app/MyApp/Customer/View/Account/applycomplete.phtml:1
./app/MyApp/Customer/View/Account/catalogue.phtml:1
./app/MyApp/Customer/View/Account/classadd.phtml:0
./app/MyApp/Customer/View/Account/orders-trade.phtml:0

第一个管道grep:0$将该列表过滤为只包含以:0结尾的行:

$> find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$

./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml:0
./app/MyApp/Customer/View/Account/studio.phtml:0
./app/MyApp/Customer/View/Account/classadd.phtml:0
./app/MyApp/Customer/View/Account/orders-trade.phtml:0

第二条管道sed 's/..$//'去掉每行的最后两个字符,只留下文件路径。

$> find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'

./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml
./app/MyApp/Customer/View/Account/studio.phtml
./app/MyApp/Customer/View/Account/classadd.phtml
./app/MyApp/Customer/View/Account/orders-trade.phtml