Eliminazione di tutti i file in una cartella tranne i file X, Y e Z


17

Ho molti file e cartelle in una cartella specifica e voglio eliminarli tutti; tuttavia, volevo mantenere i file X, Y e Z.

C'è un modo in cui posso fare qualcosa del tipo: rm * | but NOT grep | X or Y or Z


Presumo di poter usare qualche espressione regolare che farà questo?
Entro il

Risposte:


16

Invece di usare rm, potrebbe essere più facile usare find . Un comando come questo eliminerebbe tutto tranne un file chiamato esattamente "file"

find . \! -name 'file' -delete

Molte versioni di dovrebbero essere in grado di supportare il globbing e la corrispondenza delle espressioni regolari.

Potresti anche reindirizzare l'output di find a rm

find . \! -name '*pattern*' -print0 | xargs --null rm 

3
E questo ti permette di vedere esattamente quali file verranno eliminati rimuovendo -deletecosì come quali file verranno salvati rimuovendo -deletee \!.
Shawn J. Goff,

1
attento, findè ricorsivo! così anche tutte le sottodirectory dei file che non corrispondono a " pattern " verranno eliminate
Alexandre Holden Daly,

Il modo tramite xargs ha bisogno di -depth, per impedire il tentativo di eliminare le directory prima che i file siano inclusi in esse. Tuttavia, penso che anche rm non rimuoverà le directory.
utente sconosciuto

9

Uso di zsh, con setopt EXTENDED_GLOB, utilizzo ~dell'operatore ( tranne )

rm -- *~(x|y|z)

o ^operatore (negazione):

rm -- ^(x|y|z)

Tuttavia, dovresti probabilmente spostare i file altrove, quindi eliminare tutto. È molto più sicuro in termini di scivolamenti delle dita, come colpire entrare troppo presto.


5

Le versioni successive di bash hanno l' extglobopzione shell che ti dà una sintassi per fare quello che vuoi (controlla la tua pagina man in "Espansione percorso" per vedere se la tua versione installata ce l'ha):

$ shopt -s extglob  # turn on extended globbing
$ rm !(X|Y|Z)

Per provare, ti suggerisco di sostituire prima rmcon echoper vedere se l'elenco dei file da eliminare è quello che ti aspetti.


5
ls -1 | grep -v "^[XYZ]$" # | xargs rm -r

Attenzione: eseguire il comando e se i file da eliminare sono quelli giusti, eseguirlo nuovamente ed eliminare il carattere hash "#".

Se i nomi dei file sono più complicati, allora

ls -1 | egrep -v "^file1$|^filename2$|^f1le$" # | xargs rm -r

Ancora una volta, prima guarda i risultati, quindi rimuovi il segno hash.

Questa versione - come suggerito nei commenti - salva alcuni personaggi e appare un po 'più chiara.

ls -1 | egrep -v "^(file1|filename2|f1le)$" # | xargs rm -r

Una modifica suggerita da ddeimeke è di cambiare l' egrepargomento in"^(file1|filename2|f1le)$"
Michael Mrozek

Se si dispone di tre file a, be a bil primo programma cancellerà - se si mette ab nella parte grep: "^[ab]$" ae bma non a b, proprio al contrario di vostre intenzioni. Il secondo comando farà lo stesso. E anche il terzo. Non dovresti usare 'ls' negli script, con eccezioni molto, molto rare. Basta non farlo.
utente sconosciuto

3

Sposta i file che vuoi tenere lontano. Salire di un livello, eliminare la cartella. Ricreare la cartella e spostare indietro quei file.


Mi chiedo perché il meno? .. In realtà è sia più facile che più sicuro di qualsiasi altra cosa proposta da altri: semplicemente non puoi spararti in un piede colpendo un carattere speciale nel nome del file.
alex,

a) Sposti il ​​tuo file X di una directory in alto, dove esiste un file X - cancellato silenziosamente, sparito. b) Sei nella prima directory, dove non esiste "up". c) Sei a casa tua e non hai il permesso di scrivere a / home. Se inserisci i tuoi consigli in una sceneggiatura e li testerai senza problemi, e li usi in una situazione del genere - peng!
utente sconosciuto

2
a) Ehi, ho detto 'i file spostare up di un livello'? Ho detto di allontanarli. b) Quindi stai provando a rimuovere tutti i file /, eh? Non molto pratico. c) Cercare di rimuovere tutti i file nel tuo $HOMEnon è nemmeno molto pratico.
alex

Hai ragione, mi dispiace.
utente sconosciuto

0

Questo è ciò che ho impostato come script .sh per un hook di logout OSX / MacOS, funziona abbastanza bene.

#! /bin/bash
for dir in /PathToFolder/*
 do
    if [ ! "$dir" = "/PathToFolder/FolderToKeep1" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep2" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep3" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep4" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep5" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep6" ] ; then 
      echo ${dir}
      sudo rm -R $dir user
      dscl . -delete $dir
    fi 
  done

exit 0

0

Con GNU-find puoi usare l'opzione -delete, che rimuove anche le directory, se vuote:

 find tmp -not -name X -not -name Y -not -name Z -delete 

Se X, Y o Z è una directory, verranno eliminati anche i file al suo interno. find tmp -maxdepth 1 -not -name X -not -name Y -not -name Z -deleteè un modo per aggirare questo.
Gilles 'SO-smetti di essere malvagio' il

Dal momento che le cartelle in Unix sono file (tutto è un file), questo è forse ciò che si intende. La domanda dice esplicitamente: "Ho molti file e cartelle in una cartella specifica e voglio eliminarli tutti"; e se ti piace escludere Y, forse sai se Y è una directory o no.
utente sconosciuto

Ciò finirà anche per l'eliminazione tmpse non ci fossero X/ Y/ Zfile in esso. Nota !come equivalente standard di GNU -not( -deleteè anche un'estensione GNU)
Stéphane Chazelas,

@ StéphaneChazelas: Dalla domanda, eliminare le cartelle (tutte) è ciò che è stato chiesto. Dato che il botto ha bisogno di essere mascherato, preferisco digitare -not. Potrebbe dipendere dal layout della tastiera tedesca, dove Backslash ha bisogno di Alt-Gr.
utente sconosciuto
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.