Ero confuso sul perché anche le directory potate venivano stampate dal find
comando e alcuni altri intricati dettagli su come -prune
funzionava, ma sono stato in grado di capirlo con alcuni esempi.
Per eseguire gli esempi seguenti, creare le seguenti directory e file.
mkdir aa
mkdir bb
touch file1
touch aa/file1
touch bb/file3
Per creare questa struttura:
$ tree
.
├── aa
│ └── file1
├── bb
│ └── file3
└── file1
Ora usa trova per cercare le directory chiamate aa
. Nessun problema qui.
$ find . -type d -name aa
./aa
Cerca tutte le directory diverse da aa e otteniamo la directory corrente .
e ./bb
, il che ha anche senso.
$ find . -type d ! -name aa
.
./bb
Fin qui tutto bene, ma quando usiamo -prune
, find restituisce la directory che stiamo potando, che inizialmente mi ha confuso perché mi aspettavo che restituisse tutte le altre directory e non quella che è stata potata.
$ find . -type d -name aa -prune
./aa
Il motivo per cui restituisce la directory che viene eliminata è spiegato, non nella -prune
sezione delle pagine man come indicato nella risposta di Timo , ma nella EXPRESSIONS
sezione:
Se l'espressione non contiene azioni diverse da -prune
,
-print
viene eseguita su tutti i file per i quali l'espressione è vera.
il che significa che, poiché l'espressione corrisponde al aa
nome della directory, allora l'espressione verrà valutata come vera e verrà stampata perché find aggiunge implicitamente -print
a alla fine dell'intero comando. Non aggiungerà -print
, tuttavia, se si aggiunge intenzionalmente l'azione -o -print
alla fine:
find . -type d -name aa -prune -o -print
.
./file1
./bb
./bb/file3
Qui il comando find NON aggiunge più un implicito -print
, quindi la directory che stiamo potando ( aa
) non verrà stampata.
Quindi, infine, se aggiungiamo una clausola che cerca i file con un modello di nome file file*
dopo il -o
, allora devi mettere un -print
alla fine di quella seconda clausola in questo modo:
find . \( -type d -name aa -prune \) -o \( -type f -name 'file*' -print \)
./file1
./bb/file3
Il motivo per cui funziona è lo stesso: se non si inserisce a -print
nella seconda clausola, quindi poiché non esiste alcuna azione diversa -prune
dall'azione, find aggiungerà -print
automaticamente a THE END del comando, causando la -prune
stampa della clausola directory potata:
find . \( \( -type d -name aa -prune \) -o \( -type f -name 'file*' \) \) -print
./aa
./file1
./bb/file3
In generale, è necessario inserire il -print
comando nella seconda clausola. Se lo metti nel mezzo come ha fatto il poster originale, non funzionerà correttamente perché i file che verranno eliminati verranno stampati immediatamente e la seconda clausola non avrà la possibilità di scegliere i file desiderati:
find . \( -type d -name aa -prune -o -print \) -o \( -type f -name 'file*' \)
.
./file1
./bb
./bb/file3
Quindi, sfortunatamente, il poster originale ha sbagliato il comando sopra posizionandolo -print
nel posto sbagliato. Potrebbe aver funzionato per il suo caso specifico, ma non funziona nel caso generale.
Ci sono migliaia di persone che hanno difficoltà a capire come -prune
funziona. La find
pagina man dovrebbe essere aggiornata per evitare la confusione infinita in tutto il mondo su questo comando.
-print
, altrimenti l'implicito si-print
applica all'intera condizione