Come cercare il testo nell'intero file system?


53

Supponendo che lo strumento grep debba essere utilizzato, mi piacerebbe cercare la stringa di testo "800x600" in tutto il file system.

Provai:

grep -r 800x600 /

ma non funziona.

Quello che credo che il mio comando dovrebbe fare è grep ricorsivamente attraverso tutti i file / cartelle in root per il testo "800x600" ed elencare i risultati della ricerca.

Che cosa sto facendo di sbagliato?


2
E per "non funziona" intendi esattamente cosa? Non stampa alcun output, si blocca o stampa molti Permission deniederrori? L'hai eseguito come utente root o normale?
alex

Sto ottenendo un po 'di trazione, prima di tutto ero nella mia home directory utente cercando di eseguire il comando. Quindi ora ho cd / out su root. Successivamente ho provato lo stesso comando di cui sopra e ricevo molti errori di autorizzazione negata. Ok, quindi ora provo sudo grep -r 800x600 / e quindi ottengo un / proc / sysrq-trigger: errore di input / output
Level1Coder

Hmm, non so perché non funzionerebbe. È possibile ignorare gli errori di accesso facendo grep -r 800x600 / 2>/dev/null. Puoi anche provare a eseguirlo come root.
Totor,

Risposte:


64

Normalmente utilizzo questo stile di comando per scorrere grepsu un numero di file:

find / -xdev -type f -print0 | xargs -0 grep -H "800x600"

Ciò che effettivamente fa è creare un elenco di tutti i file sul sistema e, quindi, per ogni file, eseguire grepcon gli argomenti dati e il nome di ciascun file.

L' -xdevargomento dice che deve ignorare altri filesystem - questo è utile per evitare filesystem speciali come /proc. Tuttavia ignorerà anche i normali filesystem - quindi se, per esempio, la tua cartella / home si trova su una partizione diversa, non verrà cercata - dovresti dirlo find / /home -xdev ....

-type fsignifica cercare solo i file, quindi le directory, i dispositivi e altri file speciali vengono ignorati (continuerà a rientrare nelle directory e verrà eseguito grepsui file all'interno - semplicemente non verrà eseguito grepsulla directory stessa, che non funzionerebbe comunque). E l' -Hopzione per grepdirgli di stampare sempre il nome del file nel suo output.

findaccetta tutti i tipi di opzioni per filtrare l'elenco dei file. Ad esempio, -name '*.txt'elabora solo i file che terminano con .txt. -size -2Mindica file di dimensioni inferiori a 2 megabyte. -mtime -5indica i file modificati negli ultimi cinque giorni. Unisciti a questi con -a per e e -o per o , e usa le '('parentesi ')'per raggruppare le espressioni (tra virgolette per impedire alla shell di interpretarle). Quindi per esempio:

find / -xdev '(' -type f -a -name '*.txt' -a -size -2M -a -mtime -5 ')' -print0 | xargs -0 grep -H "800x600"

Dai un'occhiata man findper vedere l'elenco completo dei possibili filtri.


2
Nota che -xdevescluderà tutti gli altri filesystem, non solo quelli speciali. (ad esempio, se hai /homemontato come una partizione separata, non verrà cercato.)
cjm

Ho provato a eseguirli tutti ma entrambi restituiscono un errore -find: paths must precede expression: /
Level1Coder

1
Nota: quando non sono richieste espressioni regolari 'fgrep' è significativamente più veloce di 'grep', il che farà una grande differenza se stai cercando un albero grande.
Nathan Kidd,

1
Puoi evitare di farlo xargscon forse un'efficienza migliore facendo find / -xdev -type f -exec grep -H '800x600' +.
Totor,

3
No, il +segno alla fine del findcomando fa effettivamente la stessa cosa xargs: genera un grepprocesso con diversi argomenti.
Totor,

14

Normalmente non dovresti cercare TUTTO sul sistema. Linux usa nodi di file per tutto, quindi alcuni "file" non sono cose che vorresti cercare. Ad esempio /dev/sdaè il dispositivo a blocchi fisici per il tuo primo disco rigido. Probabilmente si desidera cercare i file system montati e non il dispositivo a disco grezzo. Inoltre c'è /dev/randomche sputa dati casuali ogni volta che li leggi. La ricerca non ha molto senso. Il /procfile system è anche problematico nel tuo caso.

Consiglierei una delle due cose.

  1. Non cercare alla radice, cerca solo i luoghi che potrebbero essere utili. Cerca /homeo /usro /etcseparatamente. Le informazioni che stai cercando sono probabilmente di un tipo specifico, quindi è probabile che si trovino comunque in una cartella specifica. Le impostazioni di configurazione dovrebbero essere in /etc. I tuoi file di dati personali dovrebbero essere presenti /home. Limitare la ricerca a un'area importante come questa ridurrà notevolmente i tuoi problemi con greps ricorsivi.

  2. Escludere le aree problematiche utilizzando --exclude-dire un insieme di cose che non ti servono in questo modo:
    grep -r --exclude-dir /proc --exclude-dir /dev --exclude-dir /tmp --exclude-dir /lost+found

Infine, non è raro imbattersi in alcuni errori "negati dal permesso" quando si fa un grep ricorsivo. Nel normale corso dell'uso ci sono file che l'utente potrebbe non essere in grado di leggere. Fintanto che questi sono solo alcuni file dispari e non cose come il dispositivo grezzo per i tuoi dischi rigidi o l'intero file system proc, va bene semplicemente ignorare gli errori. In effetti puoi farlo sulla riga di comando inviando tutti gli errori in never never land:

grep -r search_string /path 2> /dev/null

3
-Iescludere binario
Rahul Patil

2

Per semplicità, suggerirei ack-grep . Link mostra molti casi in cui ack-grepè un'opzione migliore.

Da utilizzare è, dopo l'installazione:

ack-grep pattern /

Grazie per avermelo raccomandato, ma l'ho eseguito e non mi ha dato i risultati di ricerca che mi aspettavo. Sembra che dovrò modificare molte impostazioni per ottenere quello che voglio. A partire da ora la risposta di Richard funziona subito. Guarderò in questo in futuro perché sembra utile.
Level1Coder

1

Un altro modo di vederlo è in questo modo:

grep -r /* | grep "800x600"

0

* poi ottengo un / proc / sysrq-trigger: errore di input / output

Il tuo comando funziona, ricevi questo errore perché stai cercando di scansionare i processi in esecuzione per una stringa.

Consiglio di escludere le directory di sistema con

grep -exclude-dir = {proc, sys} "800x600" /


-3

semplicemente giusto-

grep -r "800x600" /

-Che cosa non va nel tuo comando attuale sono le virgolette "". Metti sempre l'argomento stringa greptra virgolette.


3
Questo non è il problema qui. Non hai bisogno di virgolette quando fornisci questo particolare tipo di argomento grep. Provalo e vedrai. Inserisci la stringa "800x600" in un file e grep 800x600 filevedrai che funziona perfettamente. L'OP ha ovviamente qualche altro problema.
slm
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.