Come posso impedire a una ricerca di scendere nelle directory trovate?


24

Voglio trovare tutte le directory con una stringa specifica in modo da poter fare un'altra ricerca sui file contenuti all'interno.

Quindi non voglio perdere tempo ./my-search-term/dir/my-search-termecc.

Come posso smettere di ricorrere quando ho trovato la prima directory my-search-term?


3
Hai provato a trovare con -prune? Dalla pagina man: "se il file è una directory, non scendere in essa. Se viene fornito -depth, false; nessun effetto. Poiché -delete implica -depth, non è possibile utilizzare utilmente -prune e -delete insieme."
laebshade,

1
@laebshade perché non lo metti in una risposta?
jw013,

@ jw013 Non ho avuto il tempo di fornire una risposta più approfondita in quel momento.
laebshade,

Risposte:


17

L' -pruneazione findnon rientra nella directory. Puoi combinarlo con un'altra azione come -exec(l'ordine di -prunee -execnon importa, purché -prunesia eseguito in entrambi i modi).

find . -name my-search-term -prune -exec find {} … \;

Notare che l'annidamento findall'interno di a find -execpuò essere un po 'problematico: non è possibile utilizzarlo -execall'interno find, poiché il terminatore sarebbe visto come un terminatore dall'esterno find. Puoi aggirare ciò invocando una shell, ma fai attenzione al preventivo.

find . -name my-search-term -prune -exec sh -c '
    find "$@" … -exec … {\} +
' _ {} +

Le parentesi nel tuo primo comando sono necessarie? -prunerestituisce true e può essere inserito prima di -exec.
Rozcietrzewiacz,

@rozcietrzewiacz No, non sono necessari. L'abitudine di avere un -olà dentro, immagino. E immagino che mettere -pruneprima -execsia più leggibile.
Gilles 'SO- smetti di essere malvagio' il

Grazie, non ho usato l' -pruneopzione prima.
Haridsv,

Nel mio caso d'uso, questo comando: mkdir -p x1 x2; touch x1/x11 x1/x12 x2/x21 x2/x22; find . -name 'x1*' -exec rm -rf {} \;dà l'errore: find: ./x1: No such file or directory. La soluzione è aggiungere -prunealla fine del findcomando.
Haridsv,

(1) Alcune versioni di findexpand {}anche quando appare come sottostringa di un argomento a -exec. Una versione del genere findverrà soffocata dal tuo secondo comando, perché il comando {}interno find(nel comando shell) verrà sostituito dal nome della directory trovata nell'esterno find. Puoi risolverlo dicendo find . -name my-search-term -prune -exec sh -c 'find "$0" … -exec … "{"} +' {} \; cioè, usando "{"}, in cui si trasformerà la shell {}. ... (proseguendo)
Scott,

6

- soluzioni nude -

Se vuoi findsaltare il contenuto della directory trovata, ma continua a cercare in altre directory, usa -prunecome suggerito @laebshade. Il comando completo dovrebbe quindi apparire come

 find . -type d -name somename -prune -exec ...

D'altra parte, se si desidera interromperefind completamente la ricerca e dopo aver trovato la prima directory corrispondente, ciò che si sta cercando è -quit(disponibile dalla versione 4.2.3di GNU find). Questo è un po 'più complicato da usare, perché fa finduscire immediatamente - quindi -quitdeve essere posizionato alla fine del comando:

find . -type d -name somename -exec ... -quit

Affinché ciò funzioni come previsto, si deve assicurare che i -execrendimenti siano veri (in altre parole, uno stato zero ). Se vuoi che lo stato di uscita -execvenga ignorato, in modo che -quitfunzioni sempre, hai bisogno di un piccolo trucco:

find . -type d -name somename \( -exec ... -o -true \) -quit

o

find . -type d -name somename \( -exec ... -o -quit \)

o

find . -type d -name somename \( -exec ... , -quit \) # a comma before -quit

- qualche spiegazione -

La cosa più importante su come findfunziona è che tutte le azioni ("test") sono trattate come predicati logici interpretati da sinistra a destra. Pertanto, l'ultima azione (ad esempio -quit) verrà eseguita solo se l'intera parte precedente non ha restituito false . Per impostazione predefinita, tutti i test sono uniti con "AND" logico, l' -oopzione cambia il giunto in "OR".

Un elemento complicato di -oè che findpuò "ottimizzare" il comando e non eseguire la -execparte se si digita semplicemente

find . -type d -name somename -exec ... -o -quit

Per farcela, puoi forzare finda valutare tutti i predicati associati a "OR", racchiudendoli tra parentesi.

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.