Esclusione di determinati file e directory durante l'eliminazione di file


11

La mia directory di livello superiore è data. datainclude diverse directory e queste directory hanno sottodirectory. Ho bisogno di rimuovere tutti i file e le directory all'interno data/tranne alcuni file in alcune directory.

Ad esempio, i dati includono le directory 100e 101. Voglio solo mantenere a.txte b.txtfile in 100/e c.txte d.txtfile in 101/durante la rimozione di tutti gli altri file e le directory in 100e 101.

Esempio:

.
├── 100
   ├── a.txt
   ├── b.txt
   ├── c.txt
   └── d.txt
└── 101
    ├── a.txt
    ├── b.txt
    ├── c.txt
    └── d.txt

Uso il rm -rf !(a.txt|b.txt)comando ma non posso applicare questo comando automaticamente per ogni directory.

Risposte:


12

Come hai già scoperto, puoi utilizzare la extglobfunzione abilitata con:

shopt -s extglob

Ciò consente di escludere le partite in modo da poter fare cose come:

rm 100/!([ab].txt) 101/!([cd].txt)

È una buona idea testarlo echoprima. Questo esempio corrisponderà a tutto ciò 100/che è dentro a.txto no b.txte qualsiasi cosa dentro 101/cui non è c.txto d.txt. Se si 100/applicano anche le stesse regole, ad 102/esempio:

10[02]/!([ab].txt) # or
{100,102}/!([ab].txt)

Ho appena dato un esempio per le directory 100 e 101, ma in realtà il numero di sottodirectory è quasi 20. Esiste un modo per implementare il codice sopra per ogni directory senza scrivere il nome di ogni directory nella cartella principale?
deepblue

@deepblue Fornisci un esempio esatto nella tua domanda ( modifica ), in particolare non è chiaro come si rmdebba sapere quali file conservare in quali directory se non si desidera specificarlo.
dessert

7

Potresti usare findper questo. È possibile annullare i test findcon -noto !. Ciò escluderà le partite, piuttosto che trovarle.

Si dovrebbe fare attenzione a non eliminare nessuna delle directory principali dei file che si desidera conservare, in particolare la directory corrente . , quindi assicurarsi di leggere attentamente l'output prima di eliminarlo.

Sulla base del tuo esempio potresti fare qualcosa del genere dalla datadirectory.

find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt"

Aggiungi a ! -path ./path/to/dirper ogni percorso che desideri evitare di eliminare. Puoi usare metacaratteri come *, ma assicurati di citare l'espressione se lo fai, ad esempio "./path*dir", per evitare eventuali espansioni indesiderate.

findè ricorsivo per impostazione predefinita. Anche se non lo troviamo ./100qui, troveremo tutti i suoi contenuti a meno che non corrispondano al modello [ab].txt. Se non riesci a trovare tutti i nomi che desideri conservare, aggiungi un altro test:

! -path "./100/[ab].txt" ! -path ./100/foo

Questo non troverà a.txto b.txto foo, ma troverà tutti gli altri file.

Quando sei sicuro di vedere quello che vuoi, puoi aggiungere -deletealla fine per eliminare i file trovati:

find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt" -delete
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.