GNU/Linux >> Linux Esercitazione >  >> Linux

Grep ricorsivo Vs Trova / -type F -exec Grep {}; Qual è più efficiente/più veloce?

Qual è più efficiente per trovare quali file in un intero filesystem contengono una stringa:grep ricorsivo o trova con grep in un'istruzione exec? Presumo che la ricerca sarebbe più efficiente perché puoi almeno filtrare se conosci l'estensione del file o una regex che corrisponde al nome del file, ma quando conosci solo -type f che è migliore? GNU grep 2.6.3; trova (GNU findutils) 4.4.2

Esempio:

grep -r -i 'the brown dog' /

find / -type f -exec grep -i 'the brown dog' {} ;

Risposta accettata:

Non sono sicuro:

grep -r -i 'the brown dog' /*

è proprio quello che intendevi. Ciò significherebbe grep ricorsivamente in tutti i file e le directory non nascosti in / (ma guarda ancora all'interno dei file nascosti e delle directory all'interno di quelli).

Supponendo che tu intendessi:

grep -r -i 'the brown dog' /

Alcune cose da notare:

  • Non tutti i grep le implementazioni supportano -r . E tra quelli che lo fanno, i comportamenti differiscono:alcuni seguono collegamenti simbolici alle directory quando attraversano l'albero delle directory (il che significa che potresti finire per cercare più volte nello stesso file o addirittura eseguire in loop infiniti), altri no. Alcuni guarderanno all'interno dei file del dispositivo (e ci vorrà del tempo in /dev/zero per esempio) o pipe o file binari…, alcuni no.
  • È efficiente come grep inizia a cercare all'interno dei file non appena li scopre. Ma mentre cerca in un file, non cerca più altri file in cui cercare (cosa che probabilmente è altrettanto buona nella maggior parte dei casi)

Tuo:

find / -type f -exec grep -i 'the brown dog' {} ;

(rimosso il -r che non aveva senso qui) è terribilmente inefficiente perché stai eseguendo un grep per file. ; dovrebbe essere usato solo per comandi che accettano un solo argomento. Inoltre qui, perché grep cerca solo in un file, non stamperà il nome del file, quindi non saprai dove sono le corrispondenze.

Non stai guardando all'interno di file del dispositivo, pipe, collegamenti simbolici..., non stai seguendo collegamenti simbolici, ma potenzialmente stai ancora guardando all'interno di cose come /proc/mem .

find / -type f -exec grep -i 'the brown dog' {} +

sarebbe molto meglio perché come pochi grep verrebbero eseguiti i 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 find ha trovato abbastanza file da masticare, quindi ci sarà un certo ritardo iniziale. E find non continuerà a cercare altri file fino al precedente grep è ritornato. L'allocazione e il passaggio dell'elenco di file di grandi dimensioni ha un impatto (probabilmente trascurabile), quindi tutto sommato probabilmente sarà meno efficiente di un grep -r che non segue un collegamento simbolico o guarda all'interno dei dispositivi.

Correlati:come funzionano ${0##*/} e ${0%/*}?

Con gli strumenti GNU:

find / -type f -print0 | xargs -r0 grep -Hi 'the brown dog'

Come sopra, come pochi grep verranno eseguite più istanze possibili, ma find continuerà a cercare più file mentre il primo grep l'invocazione sta guardando all'interno del primo batch. Questo può o non può essere un vantaggio però. Ad esempio, con i dati archiviati su dischi rigidi rotazionali, find e grep l'accesso ai dati archiviati in posizioni diverse sul disco rallenterà la velocità effettiva del disco facendo muovere costantemente la testina del disco. In una configurazione RAID (dove find e grep potrebbe accedere a diversi dischi) o su SSD, ciò potrebbe fare una differenza positiva.

In una configurazione RAID, eseguendo diversi simultanei grep le invocazioni potrebbero anche 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 notevolmente le prestazioni. Nota comunque che il secondo grep verrà avviato solo una volta trovati file sufficienti per riempire il primo grep comando. Puoi aggiungere un -n opzione per xargs affinché ciò avvenga prima (e passare meno file per grep invocazione).

Tieni inoltre presente che se stai reindirizzando xargs output su qualsiasi cosa tranne un dispositivo terminale, quindi greps s inizierà a memorizzare nel buffer il proprio output, il che significa che l'output di quei grep s sarà probabilmente interfogliato in modo errato. Dovresti usare stdbuf -oL (ove disponibile come su GNU o FreeBSD) su di loro per aggirare il problema (potresti ancora avere problemi con righe molto lunghe (in genere>4KiB)) o far scrivere a ciascuno il proprio output in un file separato e concatenarli tutti alla fine.

Qui, la stringa che stai cercando è fissa (non un'espressione regolare), quindi usando il -F l'opzione potrebbe fare la differenza (improbabile come grep le implementazioni sanno già come ottimizzarlo).

Un'altra cosa che potrebbe fare una grande differenza è correggere le impostazioni internazionali su C se ti trovi in ​​una locale multi-byte:

find / -type f -print0 | LC_ALL=C xargs -r0 -P2 grep -Hi 'the brown dog'

Per evitare di guardare dentro /proc , /sys …, usa -xdev e specifica i file system in cui desideri eseguire la ricerca:

LC_ALL=C find / /home -xdev -type f -exec grep -i 'the brown dog' /dev/null {} +

Oppure elimina i percorsi che desideri escludere in modo esplicito:

LC_ALL=C find / ( -path /dev -o -path /proc -o -path /sys ) -prune -o 
  -type f -exec grep -i 'the brown dog' /dev/null {} +

Linux
  1. Trova -exec + Vs Trova | Xargs:quale scegliere?

  2. La stampa del nome del file insieme ai risultati di Grep in Find -exec?

  3. Rompere la ricerca se un -exec fallisce?

  4. Come trovare più stringhe nei file??

  5. trova -exec cmd {} + vs | xargs

Grep Command in Linux (Trova testo nei file)

Come trovare una stringa in un file su Linux

Trova testo nei file su Linux usando grep

grep ricorsivo:esclude directory specifiche

Trovare una directory in un terminale Linux

Quale è più efficiente:compressione tar o zip? Qual è la differenza tra tar e zip?