Non ne sono sicuro:
grep -r -i 'the brown dog' /*
è davvero quello che volevi dire. Ciò significherebbe grep in modo ricorsivo in tutti i file e le directory non nascosti /
(ma cerca comunque all'interno di file e directory nascosti all'interno di quelli).
Supponendo che volevi dire:
grep -r -i 'the brown dog' /
Alcune cose da notare:
- Non tutte le
grep
implementazioni supportano -r
. E tra quelli che lo fanno, i comportamenti differiscono: alcuni seguono collegamenti simbolici alle directory quando si attraversa l'albero delle directory (il che significa che si può finire per cercare più volte nello stesso file o addirittura eseguire cicli infiniti), altri no. Alcuni guarderanno all'interno dei file del dispositivo (e ci vorrà del tempo /dev/zero
per esempio) o pipe o file binari ..., altri no.
- È efficiente poiché
grep
inizia a cercare i file non appena li rileva. Ma mentre cerca in un file, non è più alla ricerca di più file in cui cercare (che probabilmente è altrettanto valido nella maggior parte dei casi)
Il tuo:
find / -type f -exec grep -i 'the brown dog' {} \;
(rimosso ciò -r
che non aveva senso qui) è terribilmente inefficiente perché ne stai eseguendo uno grep
per file. ;
dovrebbe essere usato solo per comandi che accettano solo un argomento. Inoltre qui, poiché grep
guarda solo in un file, non stamperà il nome del file, quindi non saprai dove si trovano le partite.
Non stai cercando all'interno dei file del dispositivo, pipe, symlink ..., non stai seguendo i symlink, ma stai ancora potenzialmente cercando cose del genere /proc/mem
.
find / -type f -exec grep -i 'the brown dog' {} +
sarebbe molto meglio perché grep
verrebbero eseguiti meno comandi possibili. Otterresti il nome del file a meno che l'ultima esecuzione non abbia un solo file. Per questo è meglio usare:
find / -type f -exec grep -i 'the brown dog' /dev/null {} +
o con GNU grep
:
find / -type f -exec grep -Hi 'the brown dog' {} +
Nota che grep
non verrà avviato fino a quando non find
avrà trovato abbastanza file per poterlo masticare, quindi ci sarà qualche ritardo iniziale. E find
non continuerà a cercare altri file fino alla grep
restituzione del precedente . L'allocazione e il passaggio dell'elenco di file di grandi dimensioni ha un impatto (probabilmente trascurabile), quindi nel complesso sarà probabilmente meno efficiente di un grep -r
che non segue il collegamento simbolico o guarda all'interno dei dispositivi.
Con gli strumenti GNU:
find / -type f -print0 | xargs -r0 grep -Hi 'the brown dog'
Come sopra, grep
verranno eseguiti il minor numero di casi possibili, ma find
continuerà a cercare altri file mentre la prima grep
chiamata viene eseguita all'interno del primo batch. Questo può essere o non essere un vantaggio però. Ad esempio, con i dati memorizzati su dischi rigidi di rotazione find
e l' grep
accesso ai dati memorizzati in diverse posizioni sul disco rallenterà il throughput del disco causando lo spostamento costante della testina del disco. In una configurazione RAID (dove find
e grep
possono accedere a diversi dischi) o su SSD, ciò potrebbe fare la differenza.
In una configurazione RAID, anche l'esecuzione di più invocazioni simultanee grep
potrebbe migliorare le cose. Sempre con strumenti GNU su storage RAID1 con 3 dischi,
find / -type f -print0 | xargs -r0 -P2 grep -Hi 'the brown dog'
potrebbe aumentare significativamente le prestazioni. Si noti tuttavia che il secondo grep
verrà avviato solo dopo aver trovato abbastanza file per riempire il primo grep
comando. È possibile aggiungere -n
un'opzione affinché xargs
ciò accada prima (e passare meno file per grep
invocazione).
Si noti inoltre che se si reindirizza l' xargs
output a qualcosa che non sia un dispositivo terminale, allora gli greps
s inizieranno a bufferizzare il loro output, il che significa che grep
probabilmente l'output di questi s verrà intercalato erroneamente. Dovresti usare stdbuf -oL
(dove disponibile come su GNU o FreeBSD) su di essi per aggirare ciò (potresti ancora avere problemi con linee molto lunghe (in genere> 4KiB)) o avere ciascuno scrivere il proprio output in un file separato e concatenarli tutto alla fine.
Qui, la stringa che stai cercando è fissa (non una regexp) quindi l'utilizzo -F
dell'opzione potrebbe fare la differenza (è improbabile poiché le grep
implementazioni sanno già come ottimizzarla).
Un'altra cosa che potrebbe fare una grande differenza è correggere le impostazioni locali su C se ci si trova in una locale multi-byte:
find / -type f -print0 | LC_ALL=C xargs -r0 -P2 grep -Hi 'the brown dog'
Per evitare di guardarti dentro /proc
, /sys
..., usa -xdev
e specifica i file system in cui vuoi cercare:
LC_ALL=C find / /home -xdev -type f -exec grep -i 'the brown dog' /dev/null {} +
O pota i percorsi che vuoi escludere esplicitamente:
LC_ALL=C find / \( -path /dev -o -path /proc -o -path /sys \) -prune -o \
-type f -exec grep -i 'the brown dog' /dev/null {} +