web-dev-qa-db-fra.com

Comment puis-je "grep" filtrer récursivement le nom des fichiers que je veux avec des caractères génériques?

Lorsque je veux effectuer une recherche grep récursive dans le répertoire en cours, je fais généralement:

grep -ir "string" .

Mais cette commande effectue une recherche dans toutes sortes de fichiers, y compris des fichiers binaires (images, audio, vidéo, etc.), ce qui ralentit considérablement le processus de recherche.

Si je fais cela, par exemple, ça ne marche pas:

grep -ir "string" *.php

Cela ne fonctionne pas car il n'y a pas de fichiers PHP dans le répertoire en cours, mais dans certains sous-répertoires du répertoire en cours, et les noms des sous-répertoires ne se terminent pas par ".php", donc grep ne 'regarde pas à l'intérieur.

Alors, comment puis-je faire une recherche récursive à partir du répertoire actuel mais en spécifiant des jokers de nom de fichier? (c'est-à-dire: rechercher uniquement dans les fichiers se terminant par une extension spécifique)

35
OMA

Utilisez l'option grep 's --include:

grep -ir "string" --include="*.php" .
49
Dan D.

Si vous avez une version de grep sans l’option --include, vous pouvez utiliser ce qui suit. Celles-ci ont été testées sur une structure de répertoire comme celle-ci:

$ tree
.
├── a
├── b
│   └── foo2.php
├── c
│   └── d
│       └── e
│           └── f
│               └── g
│                   └── h
│                       └── foo.php
├── foo1.php
└── foo.php

Où tous les fichiers .php contiennent la chaîne string.

  1. Utilisez find

    $ find . -name '*php' -exec grep -H string {} +
    ./b/foo2.php:string
    ./foo1.php:string
    ./c/d/e/f/g/h/foo.php:string
    

    Explication

    Cela trouvera tous les fichiers .php et exécutera ensuite grep -H string sur chacun d’eux. Avec l'option -exec de find, {} est remplacé par chacun des fichiers trouvés. Le -H indique à grep d'imprimer le nom du fichier ainsi que la ligne correspondante.

  2. En supposant que vous ayez une nouvelle version de bash, utilisez globstar:

    $ shopt -s globstar
    $ grep -H string  **/*php
    b/foo2.php:string
    c/d/e/f/g/h/foo.php:string
    foo1.php:string
    

    Explication

    Comme expliqué dans le manuel bash :

    globstar

    Si ce paramètre est défini, le modèle ** utilisé dans un contexte d’extension de nom de fichier correspond à tous les fichiers et à zéro ou plusieurs répertoires et sous-répertoires. Si le motif est suivi de ‘/’, seuls les répertoires et les sous-répertoires correspondent.

    Donc, en exécutant shopt -s globstar, vous activez la fonctionnalité et l'option globstar de Bash qui permet à **/*php de se développer vers tous les fichiers .php du répertoire en cours (** correspond à 0 ou plusieurs répertoires, donc **/*php correspond également à ./foo.php), qui sont ensuite suivis pour string.

14
terdon