Come combinare trova e grep per una ricerca complessa? (GNU / linux, find, grep)


17

Sto cercando di eseguire una ricerca di testo in alcuni file che condividono una struttura di directory simile, ma non si trovano nella stessa struttura di directory, in GNU / Linux.

Ho un server web con molti siti che condividono la stessa struttura ad albero (framework PHP di Code Igniter MVC), quindi voglio cercare in una directory specifica nella struttura per ogni sito, ad esempio:

/srv/www/*/htdocs/system/application/

Dove * è il nome del sito. E da quelle directory delle applicazioni , voglio cercare tutto l'albero fino alle sue foglie, per un file * .php che contiene un modello di testo, diciamo "debug (", non è necessaria alcuna espressione regolare.

So usare find e grep ma non sono bravo a combinarli.

Come lo farei?
Grazie in anticipo!

Risposte:


21

Provare

find /srv/www/*/htdocs/system/application/ -name "*.php" -exec grep "debug (" {} \; -print

Questo dovrebbe cercare ricorsivamente nelle cartelle i applicationfile con .phpestensione e passarli a grep.

Un'ottimizzazione su questo sarebbe quella di eseguire:

find /srv/www/*/htdocs/system/application/ -name "*.php" -print0 | xargs -0 grep -H "debug ("

Questo utilizza xargsper passare tutti i .phpfile di output findcome argomenti a un singolo grepcomando; ad es . L' opzione e l' opzione di assicurare che gli spazi nei nomi di file e directory siano gestiti correttamente. L' opzione passata garantisce che il nome file sia stampato in tutte le situazioni. (Per impostazione predefinita, stampa il nome file solo quando vengono passati più argomenti.)grep "debug (" file1 file2 file3-print0find-0xargs-Hgrepgrep

Da man xargs:

-0

      Gli elementi di input sono terminati da un carattere nullo anziché da uno spazio bianco e le virgolette e la barra rovesciata non sono speciali (ogni carattere è preso alla lettera). Disabilita la fine della stringa di file, che viene trattata come qualsiasi altro argomento. Utile quando gli elementi di input possono contenere spazi bianchi, virgolette o barre rovesciate. L' -print0opzione di ricerca GNU produce input adatti a questa modalità.


1
+1. Ciò eseguirà grep per ogni file php, comunque. Se ci sono molti file, puoi ottimizzare ulteriormente:find /srv/www/*/htdocs/system/application/ -name "*.php" -print0 | xargs -0 grep "debug ("
Jukka Matilainen,

@jackem concordato. Aggiornerò la mia risposta di conseguenza.
nagul,

2
Un altro piccolo miglioramento: gli xargs possono semplicemente passare un nome di file a grep, nel qual caso grep non mostrerà il nome del file se c'è una corrispondenza. Potresti voler aggiungere -H al comando grep per forzarlo a mostrare il nome del file.
Randy Orrison,

@Randy Questo è un punto molto valido.
nagul,

3
Questa è vera negromanzia, ma GNU findpuò richiedere +all'operatore invece di \;eseguire lo stesso tipo di esecuzione a processo singolo xargs. Quindi, find /srv/www/*/htdocs/system/application/ -name "*.php" -exec grep -H "debug (" {} +fa la stessa cosa xargsdell'esempio in questa risposta, ma con un fork di processo in meno (e ancora 0 rischio di problemi con i nomi di file).
Daniel Andersson,

10

findnon è nemmeno necessario per questo esempio, si può usare grepdirettamente (almeno GNU grep):

grep -RH --include='*.php' "debug (" /srv/www/*/htdocs/system/application/

e siamo passati a un singolo fork di processo.

Opzioni:

  • -R, --dereference-recursive Read all files under each directory, recursively. Follow all symbolic links, unlike -r.
  • -H, --with-filename Print the file name for each match. This is the default when there is more than one file to search.
  • --include=GLOB Search only files whose base name matches GLOB (using wildcard matching as described under --exclude).
  • --exclude=GLOB Skip any command-line file with a name suffix that matches the pattern GLOB, using wildcard matching; a name suffix is either the whole name, or any suffix starting after a / and before a +non-/. When searching recursively, skip any subfile whose base name matches GLOB; the base name is the part after the last /. A pattern can use *, ?, and [...] as wildcards, and \ to quote a wildcard or backslash character literally.

Solo per curiosità, cosa significano le -RHopzioni?
Gus,

@Gus: aggiunto un man grepestratto delle descrizioni delle opzioni al post.
Daniel Andersson,

0

La tua shell può trovare i file php e darli a grep. In bash:

shopt -s nullglob globstar
grep searchterm /srv/www/*/htdocs/system/application/**/*.php
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.