2013-01-03 8 views
61

Desidero trovare i file che terminano con _peaks.bed, ma escludono i file nelle cartelle tmp e scripts.Utilizzare il comando find ma escludere i file in due directory

è il mio comandamento come questo:

find . -type f \(-name "*_peaks.bed" ! -name "*tmp*" ! -name "*scripts*" \) 

Ma non ha funzionato. I file nella cartella tmp e script verranno comunque visualizzati.

Qualcuno ha idee a riguardo?

risposta

142

Ecco come è possibile specificare che con find:

find . -type f -name "*_peaks.bed" ! -path "./tmp/*" ! -path "./scripts/*" 

Spiegazione:

  • find . - Inizia trovare dalla directory di lavoro corrente (ricorsivamente per impostazione predefinita)
  • -type f - Specifica per find che si desidera solo file nei risultati
  • -name "*_peaks.bed" - Cercare i file con il nome che termina in _peaks.bed
  • ! -path "./tmp/*" - escludere tutti i risultati il ​​cui percorso inizia con ./tmp/
  • ! -path "./scripts/*" - esclude anche tutti i risultati il ​​cui percorso inizia con ./scripts/

Test Solution :

$ mkdir a b c d e 
$ touch a/1 b/2 c/3 d/4 e/5 e/a e/b 
$ find . -type f ! -path "./a/*" ! -path "./b/*" 

./d/4 
./c/3 
./e/a 
./e/b 
./e/5 

Sei stato piuttosto vicino, l'opzione -name considera solo il basename, dove come -path considera l'intero percorso =)

+0

Bel lavoro. Tuttavia, hai dimenticato una delle cose che l'OP voleva, per trovare i file che terminavano con '_peaks.bed'. – alex

+0

@alex doh, buona chiamata! fixed =) –

+2

Questo utilizza un numero di estensione in GNU 'find', ma poiché la domanda è codificata in Linux, non è un problema. Buona risposta. –

7

Ecco un modo si potesse fare ...

find . -type f -name "*_peaks.bed" | egrep -v "^(./tmp/|./scripts/)" 
+2

Questo ha il merito di funziona con qualsiasi versione di 'find', piuttosto che con GNU' find'. Tuttavia, la domanda è codificata in Linux, quindi non è critica. –

0

provare qualcosa di simile

find . \(-type f -name \*_peaks.bed -print \) -or \(-type d -and \(-name tmp -or -name scripts \) -and -prune \) 

e non essere troppo sorpresi se ho preso un po 'sbagliato. Se l'obiettivo è un exec (invece di stampare), basta sostituirlo.

0

per me, questa soluzione non ha funzionato su un comando exec con find, non so davvero perché, quindi la mia soluzione è

find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \; 

Spiegazione: stesso Sampson-chen uno con le aggiunte di

-prune - ignorare il percorso di procedere di ...

-o - Poi, se non può competere stampare i risultati, (potare le directory e stampare i risultati rimanenti)

18:12 $ mkdir a b c d e 
18:13 $ touch a/1 b/2 c/3 d/4 e/5 e/a e/b 
18:13 $ find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \; 

gzip: . is a directory -- ignored 
gzip: ./a is a directory -- ignored 
gzip: ./b is a directory -- ignored 
gzip: ./c is a directory -- ignored 
./c/3: 0.0% -- replaced with ./c/3.gz 
gzip: ./d is a directory -- ignored 
./d/4: 0.0% -- replaced with ./d/4.gz 
gzip: ./e is a directory -- ignored 
./e/5: 0.0% -- replaced with ./e/5.gz 
./e/a: 0.0% -- replaced with ./e/a.gz 
./e/b: 0.0% -- replaced with ./e/b.gz 
+0

L'accettato risposta non ha funzionato, ma funziona.Utilizzando prugne, find. -path ./scripts -prune -name '* _peaks.bed' -type f'. Non so come escludere più directory.Questo elenca anche il livello più alto directory esclusa anche se è specificato 'type'. Escludere via Grep sembra più semplice a meno che non si voglia usare la potatura per accelerare l'operazione di ricerca. – Mohnish

0

Si può provare di seguito:

find ./ ! \(-path ./tmp -prune \) ! \(-path ./scripts -prune \) -type f -name '*_peaks.bed' 
+1

Su una vecchia domanda del genere (4 anni!) Vuoi spiegare perché questa nuova risposta è migliore o diversa, non solo il codice "dump". – Nic3500