Escludi una sottodirectory utilizzando find


115

Ho una struttura di directory come questa

data
|___
   |
   abc
    |____incoming
   def
    |____incoming
    |____processed
   123
    |___incoming
   456
    |___incoming
    |___processed

C'è una sottocartella in entrata in tutte le cartelle all'interno della directory dei dati. Voglio ottenere tutti i file da tutte le cartelle e sottocartelle tranne le directory def / incoming e 456 / incoming. Ho provato con il seguente comando

 find /home/feeds/data -type d \( -name 'def/incoming' -o -name '456/incoming' -o -name arkona \) -prune -o -name '*.*' -print

ma non funziona come previsto.

Ravi


3
Questo non è un buon consiglio, ma ti farà uscire da molte situazioni in modo rapido e sporco: tubalo grep -v somethingper escludere ciò che non vuoi
Miquel

Risposte:


206

Funziona:

find /home/feeds/data -type f -not -path "*def/incoming*" -not -path "*456/incoming*"

Spiegazione:

  • find /home/feeds/data: inizia la ricerca ricorsiva dal percorso specificato
  • -type f: trova solo file
  • -not -path "*def/incoming*": non includere nulla con def/incomingcome parte del suo percorso
  • -not -path "*456/incoming*": non includere nulla con 456/incomingcome parte del suo percorso

ottenere un errore "trova: opzione errata -non trovare: elenco-predicati-elenco-percorsi"
Ravi

@ Ravi stai usando bash shell? L'ho appena testato sul mio terminale e funziona per me. Prova invece a copiare e incollare la soluzione se hai apportato modifiche allo script.
sampson-chen

Funziona, ma elenca le directory non i file in quelle directory.
Ravi

1
-pathcorrisponde all'intera stringa, quindi se lo fai find ., le tue -pathstringhe devono essere./path/to/directory/*
Heath Borders

1
Cordiali saluti, funzionerà -not -pathsicuramente in questo esempio, ma findsta ancora iterando nella struttura della directory e utilizzando i cicli della CPU per iterare su tutte quelle directory / file. per evitare finddi iterare su quelle directory / file (forse ci sono milioni di file lì), allora devi usare -prune(l' -pruneopzione è difficile da usare comunque).
Trevor Boyd Smith

9

Solo per motivi di documentazione: potresti dover scavare più a fondo poiché ci sono molte costellazioni di search'n'skip (come dovevo). Potrebbe risultare che pruneè tuo amico mentre -not -pathnon fa quello che ti aspetti.

Quindi questo è un prezioso esempio di 15 esempi di ricerca che escludono le directory:

http://www.theunixschool.com/2012/07/find-command-15-examples-to-exclude.html

Per collegarmi alla domanda iniziale, l'esclusione alla fine ha funzionato per me in questo modo:

find . -regex-type posix-extended -regex ".*def/incoming.*|.*456/incoming.*" -prune -o -print 

Quindi, se desideri trovare un file ed escludere ancora i percorsi, aggiungi semplicemente | grep myFile.txt.

Può dipendere anche dalla versione di ricerca. Vedo:

$ find -version
GNU find version 4.2.27
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX

5

-namecorrisponde solo al nome del file, non all'intero percorso. Vuoi usare -pathinvece, per le parti in cui stai eliminando le directory come def/incoming.


2
find $(INP_PATH} -type f -ls |grep -v "${INP_PATH}/.*/"

7
Alcune spiegazioni potrebbero trasformare questo in una risposta molto migliore.
Cris Luengo

Grazie per questo snippet di codice, che potrebbe fornire un aiuto limitato a breve termine. Una spiegazione adeguata migliorerebbe notevolmente il suo valore a lungo termine mostrando perché questa è una buona soluzione al problema e la renderebbe più utile ai futuri lettori con altre domande simili. Modifica la tua risposta per aggiungere qualche spiegazione, comprese le ipotesi che hai fatto
Shawn C.

1
Nota: questo trucco non funziona se si utilizza find ... -print0in combinazione con un successivoxargs -0
phs

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.