如何使用通配符“grep”递归过滤所需文件的名称?

OMA*_*OMA 52 linux bash grep command-line file-filter

当我想在当前目录中执行递归grep搜索时,我通常这样做:

grep -ir "string" .
Run Code Online (Sandbox Code Playgroud)

但是该命令会在各种文件中搜索,包括二进制文件(图片、音频、视频等),这会导致搜索过程非常缓慢。

例如,如果我这样做,它将不起作用:

grep -ir "string" *.php
Run Code Online (Sandbox Code Playgroud)

它不起作用,因为当前目录中没有 PHP 文件,但在当前目录中的某些子目录中,并且子目录的名称不以“.php”结尾,因此 grep 不会查看其中的内容。

那么,如何从当前目录进行递归搜索,同时指定文件名通配符?(即:只搜索以特定扩展名结尾的文件)

Dan*_* D. 73

使用grep--include选项:

grep -ir "string" --include="*.php" .
Run Code Online (Sandbox Code Playgroud)


ter*_*don 16

如果您的版本grep缺少该--include选项,则可以使用以下内容。这些都在这样的目录结构上进行了测试:

$ tree
.
??? a
??? b
?   ??? foo2.php
??? c
?   ??? d
?       ??? e
?           ??? f
?               ??? g
?                   ??? h
?                       ??? foo.php
??? foo1.php
??? foo.php
Run Code Online (Sandbox Code Playgroud)

其中所有.php文件都包含字符串string.

  1. find

    $ find . -name '*php' -exec grep -H string {} +
    ./b/foo2.php:string
    ./foo1.php:string
    ./c/d/e/f/g/h/foo.php:string
    
    Run Code Online (Sandbox Code Playgroud)

    解释

    这将找到所有.php文件,然后grep -H string在每个文件上运行。使用find's-exec选项,{}由找到的每个文件替换。该-H通知grep要打印的文件名,以及匹配线路。

  2. 假设您有足够新的 版本bash,请使用globstar

    $ shopt -s globstar
    $ grep -H string  **/*php
    b/foo2.php:string
    c/d/e/f/g/h/foo.php:string
    foo1.php:string
    
    Run Code Online (Sandbox Code Playgroud)

    解释

    bash 手册中所述

    环球之星

    如果设置,文件名扩展上下文中使用的模式 '**' 将匹配所有文件以及零个或多个目录和子目录。如果模式后跟一个“/”,则只有目录和子目录匹配。

    因此,通过运行shopt -s globstar您正在激活该功能和 Bash 的globstar选项,该选项可以**/*php扩展到.php当前目录中的所有文件(**匹配 0 个或多个目录,因此也**/*php匹配./foo.php),然后为string.