Devo eliminare tutti i file in una directory, ma escluderne alcuni. Ad esempio, in una directory con i file a b c ... z
, devo eliminare tutto tranne per u
e p
. C'è un modo semplice per farlo?
Devo eliminare tutti i file in una directory, ma escluderne alcuni. Ad esempio, in una directory con i file a b c ... z
, devo eliminare tutto tranne per u
e p
. C'è un modo semplice per farlo?
Risposte:
Quello che faccio in questi casi è digitare
rm *
Quindi premo Ctrl+ X, *per espandere *
in tutti i nomi di file visibili.
Quindi posso semplicemente rimuovere i due file che mi piace mantenere dall'elenco ed infine eseguire la riga di comando.
*
espande troppo non sta diventando troppo lungo. : -}
Ctrl
+ Shift
+ x
+*
A rm
tutti ma u,p
in bash basta digitare:
rm !(u|p)
Ciò richiede l'impostazione della seguente opzione:
shopt -s extglob
Vedi di più: glob - Greg's Wiki
shopt -s extglob
, @Ashot. Inoltre, sono solo i file, non le directory, ecco perché ho rimosso le -rf
opzioni nel tuo comando.
rm !(index).html
. Ciò eliminerà tutti i file che terminano con ".html" ad eccezione di "index.html".
Puoi usare find
find . ! -name u ! -name p -maxdepth 1 -type f -delete
!
annulla l'espressione successiva-name
specifica un nome file-maxdepth 1
farà trovare al processo solo la directory specificata ( find
per impostazione predefinita attraversa le directory)-type f
elaborerà solo i file (e non ad esempio le directory)-delete
cancellerà i fileÈ quindi possibile ottimizzare le condizioni guardando la pagina man di find
Aggiornare
Metti alla prova il tuo comando prima usando -print
invece di-delete
find . ! -name u ! -name p -maxdepth 1 -type f -print
-delete
subito dopo .
sarà un disastro (eliminerà tutti i file in CWD)
find . -maxdepth 1 -type f -name '[^up]' -delete
find
è il mio migliore amico, specialmente quando ci sono troppi file su glob
Semplice:
mv
i file desiderati in una directory superiore, rm
la directory e poi mv
nuovamente.
rm
senza -r
rimuovere le sottodirectory.
Un po 'simile a questa risposta, ma non sono necessarie opzioni speciali, per quanto ne so quanto segue è la funzionalità "antica" supportata da qualsiasi shell (vagamente) / bin / sh simile alla shell (ad esempio bash, zsh, ksh, ecc.)
rm [^up]
rm [^up]*
? Faccio cose simili piuttosto spesso.
Farlo senza trovare:
ls | grep -v '(u|p)' | xargs rm
(Modifica: "u" e "v", come in altri luoghi qui, vengono utilizzati come versioni generiche di intere regex. Ovviamente dovrai stare attento ad ancorare le tue regex per evitare di abbinare troppe cose.)
Sicuramente vorrai una sceneggiatura se farai molto di questo, come altri hanno suggerito.
-E
oegrep
u
o unp
grep -L (u|p)' * | xargs rm
dove -L
significa elencare i nomi dei file che non contengono una corrispondenza.
u
o p
, non qualsiasi file contenente a u
o a p
. È corretto. Puoi risolvere usandoegrep -v '^(u|p)$'
ls | grep -v 'vuze\|progs' | xargs rm -rf
All'epoca del floppy avevo un eseguibile dos chiamato "Tranne" che spostava temporaneamente le cose dalla directory corrente ed eseguiva un comando, quindi potevi dire:
tranne * .txt del *. *
per eliminare tutto tranne i tuoi file di testo.
Questa sarebbe una cosa piuttosto banale da implementare come uno script di shell e se questo è il tipo di cosa che è probabile che tu faccia più di due volte sembra che sarebbe una buona idea.
find . -maxdepth 1 ! -name "u" ! -name "p" -type f -exec rm -rf {} \;
Ciò eliminerà tutti i file tranne uep in unix
Per coloro che preferiscono specificare schemi di esclusione complessi arbitrari (che coprono tutti i nomi di file interessati) in uno stile emge regexp completo, posix-awk o posix-extended style (vedere la pagina man 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
-regextype
funzionerà solo su versioni GNU
find
è un'estensione del find
comando GNU . Lo stesso vale per l' -regextype
opzione. Inoltre, il tuo comando eliminerà i file anche nelle sottodirectory, mentre la domanda originale poneva chiaramente domande sui file in una directory.
Ancora un altro:
for FILE in ./*; do if [[ $FILE != ./u* ]] || [[ $FILE != ./p* ]];then rm $FILE; fi; done;
È un po 'lungo e non so se potresti facilmente trasformarlo in una funzione che possa facilmente accogliere e un numero arbitrario di argomenti, ma funziona bene.
Ed è pura bontà bash.
Ecco un'altra variante. Puoi digitare:
rm -i *
o:
rm --interactive *
Quindi rm
ti chiederà di confermare l'eliminazione di ogni file.
Uso:
find . -type f ! -name 'u' ! -name 'p' ! -name '*.ext' -delete
find . -type d ! -name 'u' ! -name 'p' ! -name '*.ext' -delete
per eliminare tutti i file comprese le directory, tranne i file u, p e .ext.
Un modo semplice che è difficile sbagliare: diciamo che vuoi eliminare tutto tranne * .pdf:
mkdir tmp
mv *.pdf tmp
rm *
mv tmp/* .
rm -r tmp