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

40

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 les examine pas.

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

OMA
la source

Réponses:

58

Utilisation grepde » --includeoption:

grep -ir "string" --include="*.php" .
Dan D.
la source
1
Ok, il semble que ma version de grep était ancienne, car elle ne disposait pas de cette option (pas étonnant que je ne sache pas comment faire cela!). J'ai reçu le message: "grep: option non reconnue` --include = *. Php '". Mais je viens de passer à un plus récent et maintenant cela fonctionne. Merci!
OMA
Je devais remplacer la période à la fin et utiliser:grep -ir "string" --include="*.php" *
Stuart le
Je pensais que la période était juste la fin de la ligne! Je n'ai pas utilisé ou besoin.
Boardtc
14

Si vous avez une version de grepcette --includeoption qui manque , 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 .phpfichiers contiennent la chaîne string.

  1. Utilisation 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 va trouver tous les .phpfichiers et ensuite exécuter grep -H stringsur chacun d'eux. Avec findl' -execoption, {}est remplacé par chacun des fichiers trouvés. Le -Hdit grepd'imprimer le nom du fichier ainsi que la ligne correspondante.

  2. En supposant que vous ayez une nouvelle version suffisante 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 de bash :

    Globstar

    Si 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 modèle est suivi d'un '/', seuls les répertoires et les sous-répertoires correspondent.

    Donc, en exécutant, shopt -s globstarvous activez la fonctionnalité et l' globstaroption de Bash qui permet de **/*phpdévelopper tous les .phpfichiers du répertoire en cours ( **correspond à 0 ou plusieurs répertoires, donc **/*phpcorrespond ./foo.phpégalement) qui sont ensuite recherchés string.

terdon
la source
-2

Utilisation */*.php

Cela fait de grep search un niveau de sous-répertoire

Dennis Nolan
la source
Quelque chose s'est mal passé lorsque les astérisques et les points ont disparu.
Dennis Nolan
Vous pouvez utiliser des backticks pour formater le code et éviter toute ambiguïté sur l'utilisation des astérisques afin de mettre l'accent sur le formatage à rebours. PS note la question demande à propos de "recherche récursive" dans le dernier paragraphe (pas mon downvote cependant).
RedGrittyBrick
Pas une réponse correcte, car ce n'est bon que pour les structures de répertoires d'un niveau, comme vous le dites, mais bon de le savoir tout de même;). Mon vote positif pour cela.
OMA