2012-07-19 8 views
10

Sto utilizzando con successo find per creare un elenco di tutti i file nella sottodirectory corrente, esclusi quelli nella sottodirectory "cache". Ecco il mio primo pezzo di codice:Piping trova risultati in grep per l'esclusione rapida delle directory

find . -wholename './cach*' -prune -o -print 

Desidero ora pipe questo in un comando grep. Sembra che dovrebbe essere semplice:

find . -wholename './cach*' -prune -o -print | xargs grep -r -R -i "samson" 

... ma questo sta tornando risultati che sono in gran parte dalla directory della cache. Ho provato a rimuovere il riferimento xargs, ma questo è ciò che ti aspetteresti, eseguendo il grep sul testo dei nomi dei file, piuttosto che sui file stessi. Il mio obiettivo è trovare "samson" in qualsiasi file che non sia contenuto nella cache.

Probabilmente girerò questo problema usando solo greps raddoppiati in questa istanza, ma sono molto curioso di sapere perché questo one-liner si comporta in questo modo. Mi piacerebbe sentire i pensieri su come modificarlo usando ancora questi due comandi (poiché ci sono dei vantaggi in termini di velocità nel farlo in questo modo).

(Questo è in CentOS 5, btw.)

risposta

9

Il wholename partita può essere il motivo per cui è ancora inclusi i file "cache". Se stai eseguendo il comando find nella directory che contiene la cartella "cache", dovrebbe funzionare. In caso contrario, prova a cambiarlo in -name '*cache*'.

Inoltre, non è necessario il -r o -R per il tuo grep, che indica di recurse attraverso le directory - ma si sta testando singoli file.

È possibile aggiornare il comando utilizzando la versione in filodiffusione, o un singolo comando:

find . -name '*cache*' -prune -o -print0 | xargs -0 grep -il "samson" 

o

find . -name '*cache*' -prune -o -exec grep -iq "samson" {} \; -print 

nota, il -l nel primo comando dice grep a "elencare il file "e non le linee che corrispondono. Lo -q nel secondo fa lo stesso; dice a grep di rispondere in silenzio quindi find stamperà quindi il nome del file.

+0

Grazie! La rimozione della ricorsione è ciò che ha fatto il trucco per me. (Le vecchie abitudini sono dure a morire, per inciso, è stato un errore di battitura da parte mia, poiché di solito uso "-r -i -I", che ha molto più senso delle ridondanti bandiere di ricorsione.) La parte "wholename" andava bene, poiché la sottodirectory indesiderata è effettivamente nel livello root della directory corrente. Quindi è ora: 'trovare. -wholename './cach*' -prune -o -print | xargs grep -i -I "samson" ' – eternalnewb

+0

Impressionante, felice è stato qualcosa di semplice =] – newfurniturey

3

Utilizzare l'opzione -exec sul trovare invece di pipe ad un altro comando. Da lì è possibile utilizzare grep "samson" {} \; per cercare samson in ogni file elencato.

Ad esempio:

find . -wholename './cach*' -prune -o -exec grep "samson" "{}" + 
3

Hai detto a grep di recitare (due volte! -r e -R sono sinonimi). Poiché uno degli argomenti che stai passando è . (la directory superiore), grep cerca in ogni file (alcuni di essi due o anche di più se sono in sottodirectory).

Se avete intenzione di usare find e grep, fare questo:

find . -path './cach*' -prune -o -print0 | xargs -0 grep -i "samson" 

Utilizzando -print0 e -0 rende il vostro lavoro lo script anche con i nomi di file che contengono spazi o caratteri di punteggiatura.

Tuttavia, probabilmente non c'è bisogno di perdere tempo con find qui, dal momento che GNU grep è in grado di escludere le directory:

grep -R --exclude-dir='cach*' -i "samson" . 

(Ciò esclude anche ./deeply/nested/directory/cache Se si desidera solo per escludere le directory di cache al. In primo luogo, utilizzare find come hai fatto.)

+0

Se ci sono troppi file nella cartella/percorso corrente, il singolo' grep' restituirà un errore "troppi argomenti" - quindi dovrai stare attento a questo da solo. – newfurniturey

+0

Grazie per aver catturato questo! Come accennato nella risposta "accettata", pulendo subito le cose fisse. Ragazzi, siete grandi. – eternalnewb

+0

@newfurniturey No, un errore "troppi argomenti" verrebbe dalla shell, se la riga di comando fosse troppo lunga (ad esempio se avessi scritto 'grep ... *' e c'erano molti file). Qui non c'è il globbing della shell, la linea di comando ha esattamente 43 caratteri. – Gilles

Problemi correlati