Come posso "grep" filtrare ricorsivamente il nome dei file che voglio con i caratteri jolly?


40

Quando voglio eseguire una ricerca ricorsiva grep nella directory corrente, di solito faccio:

grep -ir "string" .

Ma quel comando cerca all'interno di tutti i tipi di file, inclusi i file binari (immagini, audio, video, ecc ...) che si traducono in un processo di ricerca molto lento.

Se lo faccio, ad esempio, non funziona:

grep -ir "string" *.php

Non funziona perché non ci sono file PHP all'interno della directory corrente, ma all'interno di alcune delle sottodirectory nella directory corrente, ei nomi delle sottodirectory non terminano con ".php", quindi grep non appare al loro interno.

Quindi, come posso fare una ricerca ricorsiva dalla directory corrente ma anche specificare i caratteri jolly del nome file? (ovvero: cerca solo nei file che terminano con un'estensione specifica)

Risposte:


58

Usa grepl' --includeopzione:

grep -ir "string" --include="*.php" .

1
Ok, sembra che la mia versione di grep fosse vecchia, perché non aveva quell'opzione (non c'è da stupirsi perché non sono riuscito a capire come farlo!). Ho ricevuto il messaggio: "grep: opzione non riconosciuta` --include = *. Php '". Ma ho appena aggiornato a uno più recente e ora funziona. Grazie!
OMA,

Alla fine ho dovuto sostituire il periodo e utilizzare:grep -ir "string" --include="*.php" *
Stuart

Pensavo che il periodo fosse solo la fine della linea! Non ho usato o bisogno.
boardtc,

14

Se hai una versione grepche non ha l' --includeopzione, puoi usare quanto segue. Entrambi sono stati testati su una struttura di directory come questa:

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

Dove tutti i .phpfile contengono la stringa string.

  1. Uso find

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

    Spiegazione

    Questo troverà tutti i .phpfile e quindi verrà eseguito grep -H stringsu ciascuno di essi. Con l find' -execopzione, {}viene sostituito da ciascuno dei file trovati. La -Hdice grepper stampare il nome del file, così come la linea abbinato.

  2. Supponendo di disporre di una versione abbastanza nuova di bash, utilizzare globstar:

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

    Spiegazione

    Come spiegato nel manuale di bash :

    globstar

    Se impostato, il modello '**' utilizzato in un contesto di espansione del nome file corrisponderà a tutti i file e a zero o più directory e sottodirectory. Se il modello è seguito da un '/', corrispondono solo le directory e le sottodirectory.

    Quindi, eseguendo shopt -s globstarstai attivando la funzione e l' globstaropzione di Bash che fa **/*phpespandere a tutti i .phpfile nella directory corrente ( **corrisponde a 0 o più directory, quindi anche alle **/*phpcorrispondenze ./foo.php) che vengono quindi troncati string.


-2

Uso */*.php

Questo rende grep search a un livello di sottodirectory


Qualcosa è andato storto quando asterischi e punti sono scomparsi.
Dennis Nolan,

È possibile utilizzare i backtick per formattare il codice ed evitare ambiguità sull'uso degli asterischi per enfatizzare la formattazione del markdown. PS nota la domanda sulla "ricerca ricorsiva" nel paragrafo finale (non il mio downvote però).
RedGrittyBrick

Non è una risposta corretta, perché è buono solo per le strutture di directory profonde di un livello, come dici tu, ma comunque buono a sapersi;). Il mio voto per quello.
OMA,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.