2012-05-09 4 views
72

ho questa lista di file all'interno di server Linux:Come eliminare più file contemporaneamente in Bash su Linux?

abc.log.2012-03-14 
abc.log.2012-03-27 
abc.log.2012-03-28 
abc.log.2012-03-29 
abc.log.2012-03-30 
abc.log.2012-04-02 
abc.log.2012-04-04 
abc.log.2012-04-05 
abc.log.2012-04-09 
abc.log.2012-04-10 

Ho l'eliminazione dei file di registro selezionati uno per uno, usando il comando rm -rf vedere di seguito:

rm -rf abc.log.2012-03-14 
rm -rf abc.log.2012-03-27 
rm -rf abc.log.2012-03-28 

C'è un altro modo, in modo che io possa cancellare i file selezionati in una volta ??

+4

E "Dite GNU/Linux, non solo Linux", sento un tonfo sordo dai sedili posteriori. –

+8

A proposito, perché il -rf? Sono queste cartelle? f è forzare, r è ricorsivo. Funzionerà se è solo un file ma sarà avvisato, usando -rf ogni volta che si desidera eliminare qualcosa è molto (molto) (molto molto) pericoloso. (e dovresti aggiungere il tag "bash" perché "linux" è troppo ampio – Depado

+0

@BorisStitnicky - Sono curioso di sapere perché è necessario il 'GNU'? – user66001

risposta

115

Bash supporta tutti i tipi di caratteri jolly ed espansioni.

tuo caso esatto sarà gestita dal brace expansion, in questo modo:

$ rm -rf abc.log.2012-03-{14,27,28} 

che questo sarebbe ampliare ad un unico comando con tutte e tre argomenti, ed equivalente a digitando:

$ rm -rf abc.log.2012-03-14 abc.log.2012-03-27 abc.log.2012-03-28 

È importante notare che questa espansione viene eseguita dalla shell, prima che venga caricato anche lo rm.

54

Utilizzare un carattere jolly (*) per abbinare più file.

Ad esempio, il comando seguente cancellerà tutti i file con nomi che iniziano con abc.log.2012-03-.

rm -f abc.log.2012-03-* 

Mi consiglia di correre ls abc.log.2012-03-* per elencare i file in modo che si può vedere ciò che si sta per eliminare prima di eseguire il comando rm.

Per ulteriori dettagli, consultare la pagina man di Bash su filename expansion.

+0

Molto utile, ma non chiede la conferma per eliminare. Si prega di essere consapevoli. – nuriselcuk

1

Io non sono un guru di Linux, ma credo che tu voglia reindirizzare l'elenco dei file di output a xargs rm -rf. Ho usato qualcosa del genere in passato con buoni risultati. Prova prima su una directory di esempio!

EDIT - Potrei aver frainteso, in base alle altre risposte che appaiono. Se puoi usare i caratteri jolly, ottimo. Immaginavo che il tuo elenco originale che hai visualizzato fosse generato da un programma per darti la tua "selezione", quindi pensavo che la piping a xargs sarebbe stata la strada da percorrere.

5

Una wild card potrebbe funzionare bene per questo, anche se per essere sicuri che sarebbe stato meglio per rendere l'uso del jolly come minimo possibile, in modo da qualcosa sulla falsariga di questo:

rm -rf abc.log.2012-* 

Anche se dal suo aspetto, sono solo file singoli? L'opzione ricorsiva non dovrebbe essere necessaria se nessuna di queste voci è una directory, quindi è meglio non usarla, solo per sicurezza.

30

Se si desidera eliminare tutti i file il cui nome corrisponde a un determinato modulo, un carattere jolly (glob pattern) è la soluzione più semplice. Alcuni esempi:

$ rm -f abc.log.*    # Remove them all 
$ rm -f abc.log.2012*   # Remove all logs from 2012 
$ rm -f abc.log.2012-0[123]* # Remove all files from the first quarter of 2012 

Le espressioni regolari sono più potenti di jolly; è possibile alimentare l'output di grep a rm -f.Ad esempio, se alcuni dei nomi dei file iniziano con "abc.log" e alcune con "ABC.log", grep permette di fare un case-insensitive partita:

$ rm -f $(ls | grep -i '^abc\.log\.') 

Quando faccio questo, faccio funzionare l'ordine ls | grep ... prima e controllare che produce l'uscita che voglio - soprattutto se sto usando rm -f:

$ ls | grep -i '^abc\.log\.' 
(check that the list is correct) 
$ rm -f $(!!) 

dove !! espande al comando precedente. Oppure posso digitare freccia su o Ctrl-P e modificare la riga precedente per aggiungere il comando rm -f.

Si presume che si stia utilizzando la shell bash. Alcune altre shell, in particolare csh e tcsh e alcune vecchie shell derivate da sh, potrebbero non supportare la sintassi $(...). È possibile utilizzare la sintassi backtick equivalente:

$ rm -f `ls | grep -i '^abc\.log\.'` 

Il $(...) sintassi è più facile da leggere, e se siete veramente ambiziosi che possono essere nidificate.

Infine, se il sottoinsieme di file che si desidera eliminare non può essere facilmente espressa con un'espressione regolare, un trucco che uso spesso è quello di elencare i file in un file di testo temporaneo, quindi modificarlo:

$ ls > list 
$ vi list # Use your favorite text editor 

posso quindi modificare il file list manualmente, lasciando solo i file che voglio rimuovere, quindi:

$ rm -f $(<list) 

o

$ rm -f `cat list` 

(Premesso che nessuno dei nomi di file contenenti caratteri divertenti, in particolare gli spazi.)

Oppure, quando si modifica il file list, posso aggiungere rm -f all'inizio di ogni riga e poi:

$ . ./list 

o

$ source ./list 
-1

se si desidera eliminare tutti i file che appartengono a una directory in una sola volta. Per esempio; yor Il nome della directory è "log" e "log" include i file abc.log.2012-03-14, abc.log.2012-03-15, ..... ect. Devi essere al di sopra della directory di registro e

rm-rf/log/*

4

Basta utilizzare la selezione multilinea in sublime di combinare tutti i file in una sola riga e aggiungere uno spazio tra ogni nome di file e quindi aggiungi rm all'inizio della lista. Ciò è utile soprattutto quando non esiste un modello nei nomi dei file che si desidera eliminare.

[$]> rm abc.log.2012-03-14 abc.log.2012-03-27 abc.log.2012-03-28 abc.log.2012-03-29 abc.log.2012-03-30 abc.log.2012-04-02 abc.log.2012-04-04 abc.log.2012-04-05 abc.log.2012-04-09 abc.log.2012-04-10 
+0

Questa dovrebbe essere la risposta accettata in quanto risponde esplicitamente alla domanda posta. È più amichevole per le persone che sono venute qui da Google. – Alex