Come posso trovare tutti i file contenenti testo specifico su Linux?


5259

Sto cercando di trovare un modo per scansionare il mio intero sistema Linux alla ricerca di tutti i file contenenti una specifica stringa di testo. Giusto per chiarire, sto cercando del testo all'interno del file, non nel nome del file.

Quando stavo cercando come fare, mi sono imbattuto in questa soluzione due volte:

find / -type f -exec grep -H 'text-to-find-here' {} \;

Tuttavia, non funziona. Sembra visualizzare ogni singolo file nel sistema.

È vicino al modo corretto di farlo? In caso contrario, come dovrei? Questa capacità di trovare stringhe di testo nei file sarebbe straordinariamente utile per alcuni progetti di programmazione che sto realizzando.


21
ricorda che grep interpreterà qualsiasi .come un carattere jolly a carattere singolo, tra gli altri. Il mio consiglio è di usare sempre fgrep o egrep.
Walter Tross,

10
comunque eri quasi lì! Sostituisci semplicemente -Hcon -l(e forse grepcon fgrep). Per escludere i file con determinati schemi di nomi, dovrai utilizzare findin modo più avanzato. Vale comunque la pena imparare a usare find. Basta man find.
Walter Tross,

6
find … -exec <cmd> +è più facile da scrivere e più veloce di find … -exec <cmd> \;. Funziona solo se <cmd>accetta un numero qualsiasi di argomenti relativi al nome file. Il risparmio nei tempi di esecuzione è particolarmente grande se <cmd>si avvia lentamente come gli script Python o Ruby.
hagello,

Per cercare in modo non ricorsivo in un determinato percorso il comando è `grep --include = *. Txt -snw" pattern "thepath / *.
Stéphane Laurent,

@ StéphaneLaurent Penso che tu lo stia complicando troppo. Basta diregrep "pattern" path/*.txt
fedorqui "SO smettere di danneggiare" il

Risposte:


9523

Fare quanto segue:

grep -rnw '/path/to/somewhere/' -e 'pattern'
  • -ro -Rè ricorsivo,
  • -n è il numero di riga e
  • -w sta per abbinare l'intera parola.
  • -l (L minuscola) può essere aggiunto solo per dare il nome del file dei file corrispondenti.

Insieme a questi, --exclude, --include, --exclude-dirbandiere potrebbero essere utilizzati per la ricerca efficiente:

  • Questo cercherà solo attraverso quei file che hanno estensioni .c o .h:

    grep --include=\*.{c,h} -rnw '/path/to/somewhere/' -e "pattern"
    
  • Ciò escluderà la ricerca di tutti i file che terminano con l'estensione .o:

    grep --exclude=*.o -rnw '/path/to/somewhere/' -e "pattern"
    
  • Per le directory è possibile escludere una o più directory particolari tramite il --exclude-dirparametro. Ad esempio, questo esclude le directory dir1 /, dir2 / e tutte corrispondenti a * .dst /:

    grep --exclude-dir={dir1,dir2,*.dst} -rnw '/path/to/somewhere/' -e "pattern"
    

Questo funziona molto bene per me, per raggiungere quasi lo stesso scopo del tuo.

Per ulteriori opzioni, controlla man grep.


74
usa --exclude. come "grep -rnw --exclude = *. o 'directory' -e" pattern "
rakib_

98
vale la pena notare: sembra che l' ropzione sia pigra (attraversa prima la profondità, che si ferma dopo la prima directory), mentre Rè avida (attraverserà l'intero albero correttamente).
Eliran Malka,

5
grep -rnw "String stavo cercando" ha fatto quello che mi serviva. Grazie!
ViliusK,

33
Nota (specialmente per i neofiti): le virgolette nel comando sopra sono importanti.
madD7,

69
@Eliran Malka Rit rattraverserà entrambe le directory correttamente, ma Rseguirà i collegamenti simbolici.
bzeaman,

1499

Puoi usare grep -ilR:

grep -Ril "text-to-find-here" /
  • i sta per ignore case (opzionale nel tuo caso).
  • R sta per ricorsivo.
  • l sta per "mostra il nome del file, non il risultato stesso".
  • / sta per iniziare dalla radice della tua macchina.

85
In base alla mia esperienza, la -irallenta molto, quindi non usarla se non necessaria. Provalo in una determinata directory e poi generalizza. Dovrebbe essere completato in pochi minuti. Penso che un'espressione regolare la renderebbe più lenta. Ma i miei commenti si basano su supposizioni, ti suggerisco di testarlo con timedavanti alla linea.
fedorqui "SO smettere di danneggiare" il

4
Sì, lo /*rappresenta. Comunque l'ho appena provato e ho notato che /funziona.
fedorqui "SO smettere di danneggiare" il

10
Se non stai cercando usando un regex puoi usare fgrep al posto di grep sulla maggior parte dei sistemi.
markle976,

8
Sì @ markle976, infatti dall'uomo grep: fgrep is the same as grep -F -> Interpret PATTERN as a list of fixed strings.
fedorqui "SO smettere di danneggiare" il

17
È possibile sostituire / con percorso alla directory grep -Ril "text-to-find-here" ~/sites/o utilizzare. per la directory correntegrep -Ril "text-to-find-here" .
Black

329

Puoi usare ack . È come grep per il codice sorgente. Puoi scansionare l'intero file system con esso.

Basta fare:

ack 'text-to-find-here'

Nella tua directory principale.

Puoi anche usare espressioni regolari , specificare il tipo di file, ecc.


AGGIORNARE

Ho appena scoperto The Silver Searcher , che è come ack ma 3-5 volte più veloce di esso e ignora persino i pattern di un .gitignorefile.


57
Molto utile, semplice e veloce. Avvertenza: "Nelle distribuzioni derivate da Debian, ack è impacchettato come" ack-grep "perché" ack "esisteva già" (da beyondgrep.com/install ). Potresti finire con un convertitore di codice Kanji su quei Linux ...
Jose_GD

11
ack o ack-grep ha dei bei punti salienti, ma trova + grep quando usato correttamente è molto meglio nelle prestazioni
Sławomir Lenart

14
Si noti che ripgrep è più veloce di qualsiasi altra cosa menzionata qui, incluso The Silver Searcher e plain 'ol grep. Vedi questo post sul blog per la prova.
Radon Rosborough,

194

Puoi usare:

grep -r "string to be searched"  /path/to/dir

Lo rsta per ricorsivo e quindi cercherà nel percorso specificato e anche nelle sue sottodirectory. Questo ti dirà il nome del file e stampa la riga nel file in cui appare la stringa.

O un comando simile a quello che stai provando (esempio:) per la ricerca in tutti i file javascript (* .js):

find . -name '*.js' -exec grep -i 'string to search for' {} \; -print

Ciò stamperà le linee nei file in cui appare il testo, ma non stampa il nome del file.

Oltre a questo comando, possiamo scrivere anche questo: grep -rn "String to search" / path / to / directory / o / file -r: ricerca ricorsiva n: il numero di riga verrà mostrato per le corrispondenze


1
Grazie per la versione di ricerca. La mia versione grep (busybox per NAS) non ha l'opzione -r, avevo davvero bisogno di un'altra soluzione!
jc,

3
Grazie per la versione "trova"! È così importante essere in grado di filtrare per ' .js' o ' .txt', ecc. Nessuno vuole passare ore in attesa che grep finisca di cercare tutti i video multi-gigabyte dell'ultima vacanza in famiglia, anche se il comando è più facile da scrivere.
poderoso

migliore grep rispetto alla versione accettata, perché accettata non cercare le mezze parole
waza123

114

Puoi usare questo:

grep -inr "Text" folder/to/be/searched/

12
più semplice, dettagliato, ricorsivo e insensibile al maiuscolo / minuscolo. pollice su.
Francesco Casula,

se aggiungi -A3 è ancora meglio
albanx

73

Elenco di nomi di file contenenti un determinato testo

Prima di tutto, credo che tu abbia usato -Hinvece di -l. Puoi anche provare ad aggiungere il testo tra virgolette seguito da {} \.

find / -type f -exec grep -l "text-to-find-here" {} \; 

Esempio

Supponiamo che tu stia cercando file contenenti il ​​testo specifico "Licenza Apache" all'interno della tua directory. Visualizzerà risultati in qualche modo simili a quelli di seguito (l'output sarà diverso in base al contenuto della directory).

bash-4.1$ find . -type f -exec grep -l "Apache License" {} \; 
./net/java/jvnet-parent/5/jvnet-parent-5.pom
./commons-cli/commons-cli/1.3.1/commons-cli-1.3.1.pom
./io/swagger/swagger-project/1.5.10/swagger-project-1.5.10.pom
./io/netty/netty-transport/4.1.7.Final/netty-transport-4.1.7.Final.pom
./commons-codec/commons-codec/1.9/commons-codec-1.9.pom
./commons-io/commons-io/2.4/commons-io-2.4.pom
bash-4.1$ 

Rimuovere la sensibilità del case

Anche se non si utilizza il caso come "testo" vs "TESTO", è possibile utilizzare l' -iinterruttore per ignorare il caso. Puoi leggere ulteriori dettagli qui .

Spero che questo ti aiuti.


2
Questo è ciò che fa questo comando: findpasserà tutti i percorsi che trova al comando grep -l "text-to-find-here" <file found>". È possibile aggiungere restrizioni al nome del file, ad esempio find / -iname "*.txt"per cercare solo nei file il cui nome termina in.txt
Mene

1
@Ausiliare: incluso un output di esempio per evitare confusione per i lettori.
lkamal,

2
@Mene È davvero triste che il commento di Auxiliare abbia più voti dei tuoi ... anche se il loro commento è del 2014 e il tuo è il 2017 che il loro commento ha 6 quando dovrebbe avere esattamente 0 e il tuo ne aveva solo uno (ora due) isn è qualcosa a cui mi piacerebbe credere.
Pryftan,

@Mene Detto questo, non distingue tra -inamemaiuscole e minuscole, il che significa che troverà anche i file .TXT, ad esempio, così come TxT e TXt e così via.
Pryftan,

66

grep( GNU o BSD )

Puoi usare lo grepstrumento per cercare ricorsivamente la cartella corrente, come:

grep -r "class foo" .

Nota: -r- Cerca ricorsivamente le sottodirectory.

Puoi anche usare la sintassi globbing per cercare all'interno di file specifici come:

grep "class foo" **/*.c

Nota: utilizzando l' opzione globbing ( **), esegue la scansione di tutti i file in modo ricorsivo con estensione o modello specifici. Per abilitare questa sintassi, eseguire: shopt -s globstar. È inoltre possibile utilizzare **/*.*per tutti i file (esclusi quelli nascosti e senza estensione) o qualsiasi altro motivo.

Se hai l'errore che l'argomento sia troppo lungo, considera di restringere la ricerca o usa la findsintassi invece come:

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 ripgrepinvece utilizzare , come:

rg "class foo" .

Controlla 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, pto simili, dal momento che è costruito sulla cima di motore regex di Rust , che utilizza automi a stati finiti, SIMD e ottimizzazioni letterali aggressivi per rendere la ricerca molto veloce.

Supporta i pattern ignorati specificati nei .gitignorefile, quindi un singolo percorso di file può essere abbinato contemporaneamente a più pattern glob.


È possibile utilizzare i parametri comuni come:

  • -i - Ricerca insensibile.
  • -I - Ignora i file binari.
  • -w - Cerca le parole intere (al contrario della corrispondenza parziale delle parole).
  • -n - Mostra la linea della tua partita.
  • -C/ --context(ad es. -C5): aumenta il contesto, in modo da visualizzare il codice circostante.
  • --color=auto - Contrassegna il testo corrispondente.
  • -H - Visualizza il nome del file in cui è stato trovato il testo.
  • -c- Visualizza il conteggio delle righe corrispondenti. Può essere combinato con -H.

1
Trovo anche utile il globbing esteso. Ma tieni presente che se c'è un numero davvero enorme di file, puoi ottenere un errore "Elenco argomenti troppo lungo". (Anche il semplice globbing è incline a questo tipo di errore).
Yoory N.

2
Per inalare un intero file system, rg sarà molto meno doloroso di quasi tutti gli altri strumenti.
Luca

55

Se il tuo grepnon supporta la ricerca ricorsiva, puoi combinare findcon xargs:

find / -type f | xargs grep 'text-to-find-here'

Trovo questo più facile da ricordare rispetto al formato per find -exec .

Ciò genererà il nome file e il contenuto della riga corrispondente, ad es

/home/rob/file:text-to-find-here

Flag facoltativi che potresti voler aggiungere a grep:

  • -i - ricerca senza distinzione tra maiuscole e minuscole
  • -l - genera solo il nome del file in cui è stata trovata la corrispondenza
  • -h - produce solo la riga corrispondente (non il nome del file)

3
Ciò equivale a grep 'text-to-find-here'senza nome file se findnon trova nulla. Questo si bloccherà e attenderà l'input dell'utente! Aggiungi --no-run-if-emptycome opzione a xargs.
hagello,

3
Questa combinazione di find e xargs non funziona come previsto se i nomi di file o directory contengono spazi (caratteri che xargs interpreta come separatori). Usa find … -exec grep … +. Se insisti sull'uso di find insieme a xargs, usa -print0e -0.
hagello,

43
grep -insr "pattern" *
  • i: Ignora le distinzioni maiuscole e minuscole sia nel PATTERN sia nei file di input.
  • n: Prefigura ciascuna riga dell'output con il numero di riga basato su 1 all'interno del suo file di input.
  • s: Elimina i messaggi di errore relativi a file inesistenti o illeggibili.
  • r: Leggi tutti i file in ciascuna directory, in modo ricorsivo.

3
Puoi spiegare come la tua risposta migliora rispetto alle altre risposte o come è sufficientemente diversa da esse?
Amos M. Carpenter,

non molto complesso da ricordare, coprirà tutti i pattern (maiuscole / minuscole -> off, include nomi di file e numero di riga e cercherà ricorsivamente ecc.) e usando "*" alla fine cercherà tutte le directory (non è necessario specificare alcun percorso o nome della directory).
enfinet,

Mi dispiace, avrei dovuto essere più chiaro: sarebbe bello se tu potessi includere quella spiegazione nella tua risposta. Così com'è, soprattutto con così tante altre risposte simili già, è difficile vedere da una breve risposta così ciò che il vantaggio di provare che sarebbe finita la risposta accettata o uno di quelli upvoted.
Amos M. Carpenter,

6
@ AmosM.Carpenter Una cosa che adoro di questa risposta è sottolineare l'argomento sopprimere, che può aiutare a filtrare il rumore che non conta per ottenere i risultati che desideriamo davvero. Grep stampa errori come "Funzione non implementata", "Argomento non valido", "Risorsa non disponibile", ecc. Ecc. Su determinati "file".
leetNightshade,

@leetNightshade: suppongo che mi stai indirizzando il tuo commento perché ho chiesto una spiegazione sul post originale sparso. Si prega di vedere la grande revisione di Fabio per i miei commenti precedenti per avere un senso.
Amos M. Carpenter,

39

C'è una nuova utility chiamata The Silversearcher

sudo apt install silversearcher-ag

Funziona a stretto contatto con Git e altri VCS. Quindi non otterrai nulla in un .git o in un'altra directory.

Puoi semplicemente usare

ag "Search query"

E farà il compito per te!


35

Come posso trovare tutti i file contenenti testo specifico su Linux? (...)

Mi sono imbattuto in questa soluzione due volte:

find / -type f -exec grep -H 'text-to-find-here' {} \;


Se si utilizza find come nel tuo esempio, meglio aggiungere -s( --no-messages) a grep, e 2>/dev/nullalla fine del comando a un sacco Evitare di permesso negato messaggi emessi da grepe find:

find / -type f -exec grep -sH 'text-to-find-here' {} \; 2>/dev/null

find è lo strumento standard per la ricerca di file - combinato con grep quando si cerca un testo specifico - su piattaforme simili a Unix. Ilcomando find è spesso combinato con xargs proposito, il .

Esistono strumenti più veloci e più facili per lo stesso scopo - vedi sotto. Meglio provarli, a condizione che siano disponibili sulla tua piattaforma , ovviamente:

Alternative più veloci e più facili

RipGrep - lo strumento di ricerca più veloce in circolazione:

rg 'text-to-find-here' / -l

The Silver Searcher :

ag 'text-to-find-here' / -l

ack :

ack 'text-to-find-here' / -l

Nota: è possibile aggiungere anche 2>/dev/nulla questi comandi, per nascondere molti messaggi di errore.


Attenzione : a meno che tu non riesca davvero ad evitarlo, non cercare da '/' (la directory principale) per evitare una ricerca lunga e inefficiente! Quindi, negli esempi sopra, è meglio sostituire ' / ' con un nome di sottodirectory, ad esempio "/ home" a seconda di dove si desidera effettivamente cercare ...


"find è lo strumento standard per la ricerca di file contenenti testo specifico su piattaforme simili a Unix" mi sembra piuttosto ambiguo. Anche oltre a ricorsivo grep findnon cerca direttamente all'interno dei file il testo. E forse quegli strumenti aggiuntivi sono utili ad alcuni ma vecchi timer e quelli a cui sono ben abituati, ad esempio grep, non gli darebbero mai del tempo (beh, certamente non lo farò). Non dire che sono inutili però.
Pryftan,

".... contenente testo specifico ...": questa parte della frase non era accurata (perché non si trova che si occupa di questa parte della ricerca). Modificato. Grazie.
Bludzee,

Felice di essere di aiuto! L'unica cosa a prima vista è cambiare la cartella delle parole in directory ma so che è una mia crociata che non vincerò mai completamente. Non rinunciare però ...
Pryftan,

Perché non "directory" anziché "cartella", ma perché? Per favore, condividi la tua "crociata"!
Bludzee,

Sto dicendo invece usa directory! Facendo riferimento a: faresti meglio a sostituire '/' con un nome di sottocartella Ed è un mio peeve pet .. esp poiché anche Windows lo chiamava 'directory'. Ah ... forse hai capito. Perché? Bene perché è così che si chiama. Viene anche chiamato a livello di file system. E guardalo in questo modo: è mai stato chiamato (per DOS) fol? No certo che no; si chiamava dir(e credo che lo sia ancora). La cartella è una cosa inventata per (suppongo) la facilità d'uso, anche se in questo caso forse la sta scemando per gli utenti meno "avanzati"?
Pryftan,

29

Provare:

find . -name "*.txt" | xargs grep -i "text_pattern"

5
Questo è in realtà un ottimo esempio di quando NON usare xargscosì .. considera questo. echo "file bar.txt has bar" > bar.txt; echo "file foo bar.txt has foo bar" > "foo bar.txt"; echo "You should never see this foo" > foo; find . -name "*.txt" | xargs grep -i foo # ./foo:You should never see this foo. Il xargsqui abbinato il file sbagliato e non corrisponde al file di destinazione. O usa un find .. -print0 | xargs -0 ...ma è un uso inutile di una pipa o megliofind ... -exec grep ... {} +
shalomb,

29

Utilizzare pwdper cercare da qualsiasi directory ci si trovi, ricorrendo verso il basso

grep -rnw `pwd` -e "pattern"

Aggiornamento A seconda della versione di grep in uso, è possibile omettere pwd. Nelle versioni più recenti .sembra essere il caso predefinito per grep se non viene fornita alcuna directory:

grep -rnw -e "pattern"

o

grep -rnw "pattern"

farà la stessa cosa di cui sopra!


3
l'utilizzo pwdnon è affatto necessario, poiché è l'impostazione predefinita. grep -rnw "pattern"basta.
fedorqui "SO smettere di danneggiare" il

e in effetti il grep -rnwe simile è stato risposto come tre anni fa, non vedo come questa risposta stia aggiungendo valore.
fedorqui "SO smettere di danneggiare" il

La risposta selezionata non mostra lo schema predefinito e 5 persone sembravano averlo trovato utile
mahatmanich,

Cosa intendi con "modello predefinito"? La risposta accettata contiene grep -rnw '/path/to/somewhere/' -e "pattern"qual è ciò che hai qui. 5 voti dopo 2,3 milioni di visite non significano molto.
fedorqui "SO smettere di danneggiare" il

Sono d'accordo :-) ciò che mi mancava nella risposta originale è il caso d'uso in cui non devi dare un percorso o cercare ricorsivamente la directory corrente che non si riflette nella risposta accettata. Quindi è stata una buona esperienza di apprendimento su grep scavare un po 'più a fondo.
Mahatmanich,

19

grep può essere utilizzato anche se non stiamo cercando una stringa.

Semplicemente correndo,

grep -RIl "" .

stamperà il percorso di tutti i file di testo, cioè quelli che contengono solo caratteri stampabili.


2
Non vedo come sia meglio che usare un semplice lso find(per il ricorsivo)
fedorqui 'SO smettere di danneggiare'

17

Ecco i vari elenchi di comandi che possono essere utilizzati per cercare file.

grep "text string to search” directory-path

grep [option] "text string to search” directory-path

grep -r "text string to search” directory-path

grep -r -H "text string to search” directory-path

egrep -R "word-1|word-2” directory-path

egrep -w -R "word-1|word-2” directory-path

5
cosa aggiunge questo alle risposte esistenti?
fedorqui "SO smettere di danneggiare" il

@fedorqui egrepè equivalente a grep -Ee significa --extended-regexpche puoi trovare i dettagli qui unix.stackexchange.com/a/17951/196072
omerhakanbilici


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

Spiegazione dai commenti

find è un comando che ti 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 file devono soddisfare, enumera tutti gli oggetti directory.

-type f specifies that it should proceed only files, not directories etc.
-exec grep specifies that for every found file, it should run grep command, passing its filename as an argument to it, by replacing {} with the filename

15

Provare:

find / -type f -exec grep -H 'text-to-find-here' {} \;

che cercherà tutti i file system, perché / è la cartella principale.

Per l'uso della cartella home:

find ~/ -type f -exec grep -H 'text-to-find-here' {} \;

Per la cartella corrente utilizzare:

find ./ -type f -exec grep -H 'text-to-find-here' {} \;

Forse i dettagli sulle differenze di cartelle sono ovvi per molti ... ma anche molto utili per i neofiti. +1
nilon,

1
cosa aggiunge questo alle risposte esistenti?
fedorqui "SO smettere di danneggiare" il

Chiamala mia crociata ma la parola è 'directory'. Questo non è Windows (che usava comunque 'directory' - pre 9x). Per favore, smetti di dire 'cartella'. Per quanto riguarda il tuo ultimo comando non hai nemmeno bisogno del '/' solo FYI.
Pryftan,

15

Spero che questo sia di aiuto ...

Espandendo grepun po 'per fornire ulteriori informazioni nell'output, ad esempio per ottenere il numero di riga nel file in cui si trova il testo, è possibile:

find . -type f -name "*.*" -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searthtext"

E se hai idea di quale sia il tipo di file, puoi restringere la ricerca specificando le estensioni del tipo di file da cercare, in questo caso .pasO i .dfmfile:

find . -type f \( -name "*.pas" -o -name "*.dfm" \) -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searchtext"

Breve spiegazione delle opzioni:

  1. .nel findspecifica dalla directory corrente.
  2. -name" *.*": Per tutti i file (-name " *.pas" -o -name " *.dfm"): solo i *.pasOR *.dfmfile, oppure specificato con-o
  3. -type f specifica che stai cercando file
  4. -print0e --nulldall'altro lato del |(pipe) ci sono quelli cruciali, passando il nome del file dal findal grepincorporato nel xargs, permettendo il passaggio di nomi di file CON spazi nei nomi di file, permettendo a grep di trattare il percorso e il nome del file come una stringa, e non romperlo su ogni spazio.

-name '*.*'non è quello che dici; non raccoglierà su un file chiamato 'file' perché il modello non equivale a quello (no .ext); *sarebbe comunque (bene. file a parte). Ma c'è un'altra cosa: se vuoi tutti i file perché preoccuparsi di specificare un nome di file in primo luogo? Nessun altro commento - tranne per il fatto che è bello sapere che ci sono ancora persone che non usano la 'cartella' della terminologia MS (che in realtà dopo averlo detto abbastanza non avrei aggiunto ma volevo sottolineare l'affermazione leggermente errata che hai fatto con i nomi dei file, nonché la ridondanza / inutilità nel caso di "tutto").
Pryftan,

15

Un semplice findpuò funzionare a portata di mano. alias nel tuo ~/.bashrcfile:

alias ffind find / -type f | xargs grep

Avvia un nuovo terminale ed emetti:

ffind 'text-to-find-here'

14

Ho scritto uno script Python che fa qualcosa di simile. Ecco come si dovrebbe usare questo script.

./sniff.py path pattern_to_search [file_pattern]

Il primo argomento, pathè la directory in cui cercheremo ricorsivamente. Il secondo argomento, pattern_to_searchè un'espressione regolare che vogliamo cercare in un file. Usiamo il formato di espressione regolare definito nella libreria Python re . In questo script, .corrisponde anche a newline.

Il terzo argomento file_pattern, è facoltativo. Questa è un'altra espressione regolare che funziona su un nome file. Verranno considerati solo i file che corrispondono a questa espressione regolare.

Ad esempio, se voglio cercare i file Python con l'estensione pycontenente Pool(seguita da word Adaptor, faccio quanto segue,

./sniff.py . "Pool(.*?Adaptor"  .*py
./Demos/snippets/cubeMeshSigNeur.py:146 
./Demos/snippets/testSigNeur.py:259 
./python/moose/multiscale/core/mumbl.py:206 
./Demos/snippets/multiComptSigNeur.py:268 

E voilà, genera il percorso dei file corrispondenti e il numero di riga in cui è stata trovata la corrispondenza. Se viene trovata più di una corrispondenza, ogni numero di riga verrà aggiunto al nome file.


14

Se si desidera utilizzare rigorosamente, findutilizzare find + grep:

find /path/to/somewhere/ -type f -exec grep -nw 'textPattern' {} \;

passaggi:

1.Utilizzare findper cercare i file,
2. Quindi eseguire grepsu tutti.

Questo può darti il ​​potere di findtrovare i file.

  • Utilizzare -name Patternse si desidera grepsolo determinati file:

    find /path/to/somewhere/ -type f -name \*.cpp -exec grep -nw 'textPattern' {} \;

Puoi giocarci e usare diverse opzioni findper migliorare o restringere la ricerca dei file.


Qual è la differenza? Funzionerà con spazi nel percorso del file?
Peter Mortensen il

13

Uso:

grep -c Your_Pattern *

Questo riporterà quante copie del tuo modello ci sono in ciascuno dei file nella directory corrente.


13

grep è il tuo buon amico per raggiungere questo obiettivo.

grep -r <text_fo_find> <directory>

Se non ti interessa il caso del testo da trovare, usa:

grep -ir <text_to_find> <directory>

Nel mio caso sembra che cerchi ovunque anche se specifico la directory
Pathros

@Pathros Probabilmente a che fare con la ricorsione abilitata e quale directory si specifica. Detto in altro modo, la ricorsione cambia le cose in quel modo.
Pryftan,

@Pathros Oh e se ci sono delle -s nella stringa di ricerca, vorrai prima passare --a grep; che può causare effetti collaterali interessanti altrimenti!
Pryftan,

13

Sono affascinato da quanto semplice grep lo faccia con 'rl':

grep -rl 'pattern_to_find' /path/where/to/find

-r to recursively find a file / directory inside directories..
-l to list files matching the 'pattern'

Usa '-r' senza 'l' per vedere i nomi dei file seguiti dal testo in cui si trova lo schema !

grep -r 'pattern_to_find' /path/where/to/find

Funziona perfettamente ...


Questo funziona anche in Git Bash (Windows).
Peter Mortensen,

Ma implica che ogni file deve essere cercato (nessun filtro sul nome del file o livello di estensione del file, come .txt). O c'è un modo per farlo?
Peter Mortensen,

12

Per cercare la stringa e generare solo quella riga 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 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;

1
Vedo solo un aspetto negativo rispetto all'utilizzo find … -exec grep 'str' {} \;(se devi usare findaffatto).
phk,

1
Ciò si romperebbe in modo orribile se uno qualsiasi dei file fosse trovato findin spazi contenuti ... potresti finire con greppingi file sbagliati e / o perdere del tutto i file giusti. Basta usare find ... -exec grep ...se hai bisogno di usare find.. ma in questo caso è grep -r ...sufficiente.
Shalomb,

1
che senso ha usare un loop sui risultati di find per poi grep? Questo diventa inutilmente complicato.
fedorqui "SO smettere di danneggiare" il

12

C'è uno ackstrumento che farebbe esattamente quello che stai cercando.

http://linux.die.net/man/1/ack

ack -i search_string folder_path/*

È possibile ignorare la -iricerca con distinzione tra maiuscole e minuscole


2
Che cosa aggiunge questo alle risposte esistenti? Questo è stato suggerito più di tre anni fa.
fedorqui "SO smettere di danneggiare" il

1
@fedorqui 1) nessuna connessione! 2) Usa espressioni regolari 3) Ottieni i numeri di riga, il nome del file con relativo percorso, il testo evidenziato, ecc. Utili per la modifica dopo la ricerca, ad esempio "vim + lineno path / file.cpp" ti porterà direttamente alla riga di interesse. Vedi l'output del comando "ack include \ | hpp" che cerca le parole chiave "include" o "hpp" nella mia cartella di ricerca e nelle mie sottocartelle. Spero che il punto sia chiaro. Ecco l'output di esempio (Impossibile mostrare i punti salienti della parola chiave con testo semplice) process / child.hpp 11: boost / process / child.hpp process / all.hpp 21: #include <boost / process / execute.hpp>
Pal

12

Tutte le risposte precedenti suggeriscono grep e find. Ma c'è un altro modo: Usa Midnight Commander

È un'utilità gratuita (30 anni, comprovata dal tempo) che è visiva senza essere una GUI. Ha un sacco di funzioni e la ricerca di file è solo una di queste.


ranger sarebbe nella stessa idea
nilon,

11

Il comando seguente funzionerà bene per questo approccio:

find ./ -name "file_pattern_name"  -exec grep -r "pattern" {} \;

2
che senso ha usare finde quindi grep -r? Sono pensati per lo stesso, quindi questo è ridondante.
fedorqui "SO smettere di danneggiare" il

ohh !! corretto, In realtà trova è per eseguire grep su file filtrati e non tutti, grazie
Pradeep Goswami

2
tuttavia, ciò non ha alcun senso, è possibile filtrare con find.
fedorqui "SO smettere di danneggiare" il

11

Evita il fastidio e installa ack-grep. Elimina molti problemi di autorizzazione e quotazione.

apt-get install ack-grep

Quindi vai alla directory che desideri cercare ed esegui il comando di seguito

cd /
ack-grep "find my keyword"
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.