Come usare il comando "grep" per trovare il testo incluse le sottodirectory

286

Voglio trovare tutti i file che contengono una specifica stringa di testo. Il comando grep funziona, ma non so come usarlo per ogni directory (posso farlo solo per la mia directory corrente). Ho provato a leggere man grep , ma non ha dato alcun aiuto.

    
posta Smile.Hunter 01.08.2011 - 13:38

11 risposte

370

Sarebbe meglio usare

grep -rl "string" /path

dove

  • L'opzione -r (o --recursive ) viene utilizzata per attraversare anche tutte le sottodirectory di /path , mentre
  • L'opzione -l (o --files-with-matches ) viene utilizzata per stampare solo i nomi dei file corrispondenti e non le linee corrispondenti (questo potrebbe anche migliorare la velocità, dato che grep interrompe la lettura di un file alla prima corrispondenza con questa opzione).
risposta data enzotib 01.08.2011 - 13:55
136

Se stai cercando righe corrispondenti ai file, il mio comando preferito è:

grep -Hrn 'search term' path/to/files
  • -H fa stampare il nome del file (implicito quando vengono cercati più file)
  • -r esegue una ricerca ricorsiva
  • -n fa stampare il numero di riga

path/to/files può essere . per cercare nella directory corrente

Altre opzioni che trovo molto utili:

  • -I ignora i file binari (complemento: -a considera tutti i file come testo)
  • -F considera search term come letterale, non come espressione regolare
  • -i esegue una ricerca insensibile alle maiuscole / minuscole
  • --color=always per forzare i colori anche durante il piping attraverso less . Per fare in modo che less supporti i colori, devi utilizzare l'opzione -r :

    grep -Hrn search . | less -r
    
  • --exclude-dir=dir utile per escludere le directory come .svn e .git .

    
risposta data Lekensteyn 01.08.2011 - 14:27
21

Credo che tu possa usare qualcosa del genere:

find /path -type f -exec grep -l "string" {} \;

Spiegazione dei commenti

find è un comando che consente di trovare file e altri oggetti come directory e collegamenti nelle sottodirectory di un determinato percorso. Se non si specifica una maschera che i nomi dei file devono soddisfare, enumera tutti gli oggetti directory.

  • -type f specifica che dovrebbe elaborare solo i file, non le directory ecc.
  • -exec grep specifica che per ogni file trovato, dovrebbe eseguire il comando grep, passandone il nomefile come argomento, sostituendo {} con il nome file
risposta data dmityugov 01.08.2011 - 13:48
17

Il mio comando predefinito è

grep -Rin string *

Uso un maiuscolo 'R' perché ls lo usa per ricorsivo. Poiché grep accetta entrambi, non c'è motivo di non usarlo.

EDIT: per HVNSweeting, apparentemente -R seguirà link simbolici dove -r non lo farà.

    
risposta data user606723 01.08.2011 - 16:43
11

Se sei disposto a provare qualcosa di nuovo, dai un ack un colpo. Il comando per cercare ricorsivamente la directory corrente per string è:

ack string

L'installazione è abbastanza semplice:

curl http://betterthangrep.com/ack-standalone > ~/bin/ack && chmod 0755 !#:3

(A condizione che tu abbia già ottenuto la directory ~/bin ed è preferibilmente nel tuo PATH .)

    
risposta data Konrad Rudolph 01.08.2011 - 17:09
3

Il comando rgrep è dedicato a tale esigenza

Se non disponibile, puoi farlo in questo modo

mkdir -p ~/bin
cd ~/bin
wget http://sdjf.esmartdesign.com/files/rgrep
chmod +x rgrep

Puoi impostare direttamente le opzioni di grep come descritto sopra.

Personalmente uso

[[  ${#args} -lt 5 && "${args//[[:space:]]/}" == "-i" ]] && args="-Hin"
args="${args:--Hns} --color=auto"

argomento correlato: come usare sempre rgrep con il colore

    
risposta data mnono 02.01.2015 - 14:58
2

Aggiornamento 2:

Questa riga di comandi che utilizza find e grep risolve il problema:

$ find path_to_search_in -type f -exec grep -in searchString {} 2> /dev/null +

--color=<always or auto> per l'output colorato:

$ find path_to_search_in -type f \
            -exec grep --color=always -in searchString {} 2>/dev/null +

Esempio:

$ find /tmp/test/ -type f -exec grep --color=auto -in "Search string" {} 2>/dev/null +

Un esempio di esecuzione nello snapshot di seguito:

Aggiornamento 1:

Puoi provare il seguente codice; come funzione in .bashrc o .bash_aliases o in uno script:

wherein () 
{ 
    for i in $(find "" -type f 2> /dev/null);
    do
        if grep --color=auto -i "" "$i" 2> /dev/null; then
            echo -e "3[0;32mFound in: $i 3[0m\n";
        fi;
    done
}

Utilizzo: wherein /path/to/search/in/ searchkeyword

Esempio:

$ wherein ~/Documents/ "hello world"

(Nota: come suggerito nei commenti sotto di @enzotib, questo non funziona con file / directory inclusi spazi nei loro nomi).

Post originale

Per cercare la stringa ed emettere solo quella linea con la stringa di ricerca:

$ for i in $(find /path/of/target/directory -type f); do \
    grep -i "the string to look for" "$i"; done

per esempio:.

$ for i in $(find /usr/share/applications -type f); \
    do grep -i "web browser" "$i"; done

Per visualizzare il nome del file contenente la stringa di ricerca:

$ for i in $(find /path/of/target/directory -type f); do \
    if grep -i "the string to look for" "$i" > /dev/null; then echo "$i"; fi; done;

per esempio:.

$ for i in $(find /usr/share/applications -type f); \
    do if grep -i "web browser" "$i" > /dev/null; then echo "$i"; \
    fi; done;
    
risposta data precise 25.01.2014 - 12:11
1

Lo faccio usando xargs, un comando molto sottovalutato

find ./ -type f -print0 | xargs -0 grep 'string_you_are_looking_for'

find ./ fornisce un elenco ricorsivo di tutti i file in una cartella corrente quindi lo conduci su xargs che esegue il comando grep su ognuno di quei file

    
risposta data deadprogrammer 01.08.2011 - 17:30
0

So che ci sono molte risposte qui, ma qui c'è un'alternativa se desideri aggiungere altre restrizioni durante la ricerca dei file:

find . -type f -exec grep --quiet string_to_look_for {} ';' -print

Funziona perché grep restituirà 0 se ha trovato un risultato, 1 altrimenti. Ad esempio puoi trovare file di 1 MB di grandi dimensioni e contenenti qualcosa:

find . -type f -exec grep --quiet string_to_look_for {} ';' -size 1M -print

Per più requisiti, probabilmente si desidera utilizzare il flag di ottimizzazione -O esistente in GNU grep.

    
risposta data Ztyx 11.03.2015 - 14:56
0

Uno script (find-in-code) per cercare in C, codice CPP:

#!/bin/sh

find . \( -iname "*.c" -o -iname "*.cpp" -o -iname "*.h" \) -type f -print0 | xargs -0 grep --color -n ""

Usa:

find-in-code "search string"
    
risposta data nvd 11.06.2015 - 18:49
0

grep ( GNU o BSD )

Puoi utilizzare lo strumento grep per cercare in modo ricorsivo la cartella corrente con il parametro -r , ad esempio:

grep -r "pattern" .

Nota: -r - Cerca ricorsivamente sottodirectory

Per cercare all'interno di file specifici, puoi utilizzare una sintassi globbing come:

grep "class foo" **/*.c

Nota: utilizzando l'opzione globbing ( ** ), esegue la scansione di tutti i file in modo ricorsivo con un'estensione o un modello specifico. Per attivare questa sintassi, esegui: shopt -s globstar . Puoi anche utilizzare **/*.* per tutti i file (esclusi quelli nascosti e senza estensione) o qualsiasi altro modello.

Se hai l'errore che il tuo argomento è troppo lungo, prendi in considerazione la possibilità di restringere la ricerca o utilizzare invece la sintassi find , ad esempio:

find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'

In alternativa usa ripgrep .

ripgrep

Se stai lavorando su progetti più grandi o file di grandi dimensioni, dovresti usare ripgrep invece, come:

rg "pattern" .

Leggi i documenti, i passaggi di installazione o il codice sorgente nella pagina del progetto GitHub .

È molto più veloce di qualsiasi altro strumento come GNU / BSD grep , ucg , ag , sift , ack , pt o simile, poiché è costruito in cima a l'espressione regolare di Rust motore che utilizza automi finiti, SIMD e ottimizzazioni letterali aggressive per rendere la ricerca molto veloce.

Supporta i pattern di ignora specificati nei file .gitignore , quindi un singolo percorso file può essere confrontato simultaneamente con più pattern glob.

Puoi usare i parametri comuni come:

  • -i - Ricerca insensibile.
  • -I - Ignora i file binari.
  • -w - Cerca le parole intere (in opposizione a corrispondenza di parole parziali).
  • -n - Mostra la riga della tua corrispondenza.
  • -C / --context (ad esempio -C5 ) - Aumenta il contesto, quindi vedi il codice circostante.
  • --color=auto - Segna il testo corrispondente.
  • -H : visualizza il nome del file in cui viene trovato il testo.
  • -c - Visualizza il conteggio delle linee corrispondenti. Può essere combinato con -H .
risposta data kenorb 11.04.2018 - 13:21

Leggi altre domande sui tag