2013-01-08 12:17:05 +0000 2013-01-08 12:17:05 +0000
123
123

Come cancellare tutti i file in una directory tranne alcuni?

Ho bisogno di eliminare tutti i file in una directory, ma escluderne alcuni. Per esempio, in una directory con i file a b c ... z, ho bisogno di cancellare tutti tranne u e p. C'è un modo semplice per farlo?

Risposte (17)

144
144
144
2013-01-08 12:34:49 +0000

Per rm tutti tranne u,p in bash basta digitare:

rm !(u|p)

Questo richiede che la seguente opzione sia impostata:

shopt -s extglob

Vedi altro: glob - Greg’s Wiki

108
108
108
2013-01-08 12:18:23 +0000

Quello che faccio in quei casi è digitare

rm *

Poi premo Ctrl+X,* per espandere * in tutti i nomi di file visibili.

Poi posso semplicemente rimuovere i due file che mi piace tenere dalla lista e infine eseguire la linea di comando.

71
71
71
2013-01-08 12:35:05 +0000

Puoi usare find

find . ! -name u ! -name p -maxdepth 1 -type f -delete
  • ! nega l'espressione successiva
  • -name specifica un nome di file
  • -maxdepth 1 farà processare a find solo la directory specificata (find di default attraversa le directory)
  • -type f processerà solo i file (e non per esempio le directory)
  • -delete cancellerà i file

Puoi poi mettere a punto le condizioni guardando la man page di find

Aggiornamento

  • Tieni presente che l'ordine degli elementi delle espressioni è significativo (vedi la documentazione)
  • Prova prima il tuo comando usando -print invece di -delete
43
43
43
2013-01-08 12:22:58 +0000

Semplice:

mv i file che volete in una directory superiore, rm la directory e poi mv di nuovo.

15
15
15
2013-01-08 14:22:21 +0000

Un po’ simile a questa risposta ma non sono necessarie opzioni speciali, per quanto ne so la seguente è una funzionalità “antica” supportata da qualsiasi shell (vagamente) simile a /bin/sh (per esempio bash, zsh, ksh, ecc)

rm [^up]
11
11
11
2013-01-09 03:54:14 +0000

Farlo senza trovare:

ls | grep -v '(u|p)' | xargs rm

(Edit: “u” e “v”, come in altri posti qui, sono usati come versioni generiche di intere regex. Ovviamente vorrete fare attenzione ad ancorare le vostre regex per evitare di far corrispondere troppe cose).

Avrete sicuramente bisogno di uno script se avete intenzione di fare molto di questo, come altri hanno suggerito.

6
6
6
2013-01-09 22:34:13 +0000

In zsh:

setopt extended_glob # probably in your .zshrc

poi

rm ^(u|p)

oppure

rm *~(u|p)

Il secondo funzionerà anche se avete ^ in $histchars per la sostituzione della storia, e naturalmente potete mettere un glob arbitrario prima del ~.

5
5
5
2013-01-08 16:32:06 +0000

GLOBIGNORE prende una lista separata da due punti

GLOBIGNORE=u:p
rm *
3
3
3
2013-01-08 17:58:46 +0000
find . -maxdepth 1 ! -name "u" ! -name "p" -type f -exec rm -rf {} \;

Questo cancellerà tutti i file tranne u e p in unix

3
3
3
2013-01-08 17:02:15 +0000

All'epoca dei floppy avevo un eseguibile dos chiamato “Except” che spostava temporaneamente le cose fuori dalla directory corrente ed eseguiva un comando, così si poteva dire:

except \*.txt del \*.\*

per cancellare tutto tranne i vostri file di testo.

Questa sarebbe una cosa abbastanza banale da implementare come uno script di shell e se questo è il tipo di cosa che probabilmente farete più di due volte sembra essere una buona idea.

2
2
2
2013-01-08 18:16:45 +0000

Per coloro che preferiscono specificare schemi di esclusione arbitrari e complessi (che coprono tutti i nomi di file interessati) in uno stile regexp emacs, posix-awk o posix-extended completo (vedere la pagina man di find) raccomanderei questo. Esclude u e p nella directory corrente in questo esempio. Questo può essere utile per gli script.

find -regextype posix-awk ! -regex './(u|p)' -print0 | xargs -0 rm -rf
1
1
1
2014-09-24 03:05:26 +0000

Ancora un altro:

for FILE in ./*; do if [[$FILE != ./u*]] || [[$FILE != ./p*]];then rm $FILE; fi; done;

È un po’ lungo e non so se si potrebbe facilmente trasformarlo in una funzione che potrebbe facilmente ospitare un numero arbitrario di argomenti, ma funziona bene.

E è pura bontà bash.

1
1
1
2014-10-22 12:37:57 +0000

Ecco un'altra variante. Potete digitare:

rm -i *

oppure:

rm --interactive *

Quindi rm vi chiederà di confermare la cancellazione di ogni file.

1
1
1
2016-09-11 02:33:03 +0000

Usate:

find . -type f ! -name 'u' ! -name 'p' ! -name '*.ext' -delete
find . -type d ! -name 'u' ! -name 'p' ! -name '*.ext' -delete

per cancellare tutti i file, comprese le directory, tranne i file u, p e .ext.

1
1
1
2013-01-09 20:54:59 +0000

Io uso sempre:

rm [a-o,q-t,v-z]*

Questo vi permetterà di definire quanto granulare volete fare. Quindi se volete cancellare i file da a a o e Z potete usare:

rm [a-o,z]*
1
1
1
2013-04-01 12:44:13 +0000

Ancora un'altra versione che usa xargs:

ls -1 | grep -v do_not_delete | xargs -I files rm "files"

Nota che xargs -I è necessario per gestire correttamente i nomi di file che includono spazi.

0
0
0
2013-10-22 07:06:44 +0000

Un modo semplice che è difficile da sbagliare: diciamo che volete cancellare tutto tranne *.pdf:

mkdir tmp
mv *.pdf tmp
rm *
mv tmp/* .
rm -r tmp