Come rimuovo tutti i file in una cartella tranne alcuni file specificati?


11

Voglio rimuovere tutti i file in una directory lasciando solo alcuni file specificati, non hanno nulla in comune per nome. Come potrei farlo?

Ad esempio, i nomi dei file che voglio conservare sono:

file_1.png, another_file.jpg,some_music.mp3

Risposte:


14

Se stai usando bash:

shopt -s extglob
rm -- !(file1|file2|file3)

La prima riga attiva solo la corrispondenza estesa del modello e successivamente ne usiamo una:

!(pattern-list) corrisponde a qualsiasi cosa tranne uno dei modelli indicati

e l'elenco dei modelli è un elenco di uno o più motivi separati da un |.


O con zsh

setopt extendedglob
rm -- ^(file1|file2)

O, più portatile, usando find:

find . -maxdepth 1 ! -name 'file1' ! -name 'file2' -type f -exec rm -v {} +

3
Potrebbe essere utile includere come restituire il comportamento facoltativo della shell ( shopt -u extglob).
geedoubleya,

7

Crea una sottodirectory tmp, sposta tutti i file che vuoi conservare in quella directory ed esegui rm -f *successivamente. Ciò non influirà sulla tmpdirectory.

Dopo di che basta fare:

mv tmp/* .
rmdir tmp

(Supponendo che nessuno dei file spostati inizi con un punto).

Questo è uno dei pochi casi in cui ha senso utilizzare il mouse e un browser di file come Nautilus in cui è possibile effettivamente fare Ctrlclic sui pochi file che si desidera conservare e quindi utilizzare il menu: Edit -> Invert Selectionper ottenere gli altri file e quindi eliminare quelli .


lo spostamento dei file nella directory tmp suona bene. Comunque, devo farlo con la riga di comando. Grazie!
AGamePlayer

3
@AwQiruiGuo Il tmp ha il vantaggio di separare prima i file in due set, prima di rimuovere irrevocabilmente quelli che non vuoi. Quindi puoi eseguire un lsper vedere se non hai perso nessuno dei file che vuoi conservare.
Anthon,

2

Aggiungi i nomi dei file che desideri conservare in un file di testo, uno per riga. Questo file non dovrebbe trovarsi nella directory o dovresti aggiungere anche il suo nome.

Se il nome della directory è foo e il nome del file è bar , procedere come segue.

find foo -type f -print0|grep -vzZ -f bar|xargs -0 rm

Questo fa quanto segue:

  1. find -type fcerca i nomi di tutti i file in foo e nelle sue sottodirectory e li stampa su STDOUT. Con l'opzione -print0delimita i nomi dei file con byte NUL.
  2. grep -v -f baresclude tutti i nomi di file che corrispondono a una riga nella barra . Con l'opzione -ztratta il suo input come un insieme di linee delimitate dal byte NUL, con l'opzione -Zdelimita il suo output con un byte NUL.
  3. xargs rmchiama rmripetutamente per eliminare i file. Con l'opzione -0tratta il suo input come un insieme di linee delimitate dal byte NUL.

Funziona con nomi di file contenenti spazi bianchi.


Questo non funzionerà poiché i nomi dei file possono contenere delle righe.
Anthon,

@Anthon ha cambiato le opzioni di find, grep, xargs per far fronte a nomi di file contenenti spazi bianchi, tra cui newline
Mathias Weidner

Se vuoi usare find, preferirei farlofind . -maxdepth 1 ! -name 'file1' ! -name 'file2' -type f -exec rm -vi {} +
jimmij
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.