GNU/Linux >> Linux Esercitazione >  >> Linux

Elimina tutti i file tranne che in una determinata sottodirectory con Trova?

Voglio eliminare ricorsivamente tutti i file a cui non si accede da un po' di tempo nella cartella a , ad eccezione di tutti i file nella sottocartella b .

find a ( -name b -prune ) -o -type f -delete

Tuttavia, ricevo un messaggio di errore:

trova:l'azione -delete attiva automaticamente -depth, ma -prune non esegue
nulla quando -depth è attivo. Se vuoi continuare comunque,
usa esplicitamente l'opzione -depth.

Aggiunta di -depth causa tutti i file in b da includere, che deve non succedere.

Qualcuno conosce un modo sicuro per farlo funzionare?

Risposta accettata:

un modo è usare -exec rm invece di -delete .

find a ( -name b -prune ) -o -type f -exec rm {} +

in alternativa usa -not -path invece di -prune :

find a -not -path "*/b*" -type f -delete

Spiegazione del perché -prune collide con -delete :

trova lamentele quando provi a usare -delete con -prune perché -delete implica -depth e -depth rende -prune inefficace.

osserva il comportamento di trova con e senza -depth :

$ find foo/
foo/
foo/f1
foo/bar
foo/bar/b2
foo/bar/b1
foo/f2

Non vi è alcuna garanzia sull'ordine in una singola directory. Ma c'è una garanzia che una directory venga elaborata prima del suo contenuto. Nota foo/ prima di qualsiasi foo/* e foo/bar prima di qualsiasi foo/bar/* .

Questo può essere annullato con -depth .

$ find foo/ -depth
foo/f2
foo/bar/b2
foo/bar/b1
foo/bar
foo/f1
foo/

Nota che ora tutti i foo/* appaiono prima di foo/ . Lo stesso con foo/bar .

maggiori spiegazioni:

  • -prune impedisce a find di scendere in una directory. In altre parole -prune salta il contenuto della directory. Nel tuo caso -name b -prune significa che quando trova raggiunge una directory con il nome b salterà la directory comprese tutte le sottodirectory.
  • -depth fa find per elaborare il contenuto di una directory prima della directory stessa. Ciò significa che nel momento in cui find elabora la voce di directory b il suo contenuto è già stato elaborato. Quindi -prune è inefficace con -depth in vigore.
  • -delete implica -depth quindi può eliminare prima il contenuto e poi la directory vuota. -delete rifiuta di eliminare le directory non vuote.

Spiegazione del metodo alternativo:

find a -not -path "*/b*" -type f -delete

Questo potrebbe essere più facile da ricordare o meno.

Questo comando scende ancora nella directory b ed elabora ogni singolo file in esso contenuto solo per -not di respingerli. Questo può essere un problema di prestazioni se la directory b è enorme.

-path funziona in modo diverso da -name . -name corrisponde solo al nome (del file o della directory) mentre -path corrisponde all'intero percorso. Ad esempio, osserva il percorso /home/lesmana/foo/bar . -name bar corrisponderà perché il nome è bar . -path "*/foo*" corrisponderà perché la stringa /foo è nel percorso. -path ha alcune complessità che dovresti capire prima di usarlo. Leggi la pagina man di find per maggiori dettagli.

Correlati:ado -Trova significato- Cerca nel dizionario!

Attenzione che questo non è infallibile al 100%. Ci sono possibilità di "falsi positivi". Il modo in cui il comando è scritto sopra salterà qualsiasi file che ha una directory padre il cui nome inizia con b (positivo). Ma salterà anche qualsiasi file il cui nome inizia con b indipendentemente dalla posizione nell'albero (falso positivo). Questo può essere risolto scrivendo un'espressione migliore di "*/b*" . Questo è lasciato come esercizio per il lettore.

Presumo che tu abbia usato a e b poiché i segnaposto e i nomi reali sono più simili a allosaurus e brachiosaurus . Se metti brachiosaurus al posto di b quindi la quantità di falsi positivi sarà drasticamente ridotta.

Almeno i falsi positivi saranno non cancellato, quindi non sarà così tragico. Inoltre, puoi verificare la presenza di falsi positivi eseguendo prima il comando senza -delete (ma ricorda di inserire la -depth implicita ) ed esaminare l'output.

find a -not -path "*/b*" -type f -depth

Linux
  1. Centos:rinominare tutti i file con un certo nome?

  2. Eliminare tutti i file in una cartella tranne l'ultimo (più recente) 20?

  3. Elenca tutti i file di immagini grafiche con find?

  4. Come eliminare tutti i file in una directory tranne alcuni?

  5. Elimina tutte le cartelle all'interno di una cartella tranne una con un nome specifico

Trova i file persi con Scalpel

Elimina tutti i file tranne i 3 più recenti nello script bash

Elimina i file corrispondenti in tutte le sottodirectory

Trova directory con tutti i file all'interno più vecchi di X?

Come rimuovere tutti i file che iniziano con una determinata stringa in Linux

Imposta nginx.conf per negare tutte le connessioni ad eccezione di determinati file o directory