rm -rf tutti i file e tutti i file nascosti senza. & .. errore


83

rm -rf /some/path/* elimina tutti i file non nascosti in quella directory (e sottocartelle).

rm -rf /some/path/.* elimina tutti i file nascosti in quella directory (ma non i sottodirigi) e fornisce anche il seguente errore / avviso:

rm: cannot remove directory: `/some/dir/.'
rm: cannot remove directory: `/some/dir/..'

Qual è il modo corretto per rimuovere ricorsivamente tutti i file e le cartelle nascosti e non nascosti in una directory di destinazione senza ricevere l'avviso / errore su .e ..?

Risposte:


40

Puoi sempre inviare messaggi di errore a /dev/null

rm -rf /some/path/.* 2> /dev/null

Potresti anche solo

rm -rf /some/path/
mkdir /some/path/

... quindi non dovrai prima preoccuparti dei file nascosti.


2
E se volessi cancellare solo i file nascosti?
CMCDragonkai,

@CMCDragonkai dovrebbe essere una domanda diversa, ma puoi trovare la soluzione nella risposta di Gilles ( rm ..?* .[!.]*dovrebbe farlo).
evilsoup,

15
L'eliminazione e la ricreazione della directory non comporta il rischio che le autorizzazioni dei file non siano subito dopo (particolarmente importante negli ambienti server). Chi potrebbe creare automaticamente la cartella con le stesse autorizzazioni di prima?
Yo Ludke,

1
@YoLudke Hai assolutamente ragione, in molte situazioni non importa ma cancellare la cartella e ricrearla non è semanticamente equivalente allo svuotamento di quella cartella; quindi fai attenzione!
Thomas,

L'eliminazione della directory non è sempre possibile. Nel mio caso la directory è un volume docker e mentre posso fare quello che voglio all'interno del volume, non posso cambiare il volume stesso dal contenitore.
dovidweisz,

84

*corrisponde a tutti i file non punto, .[!.]*corrisponde a tutti i file punto tranne .e ai file il cui nome inizia con .., e ..?*corrisponde a tutti i file punto punto tranne ... Insieme corrispondono a tutti i file diversi da .e ... Se uno di questi tre modelli non corrisponde a nulla, si espande a se stesso; rm -fnon importa argomenti inesistenti, quindi non importa.

rm -rf ..?* .[!.]* *

Puoi anche usare find. Questo è più complesso ma ha il vantaggio di funzionare anche se ci sono così tanti file che i caratteri jolly sopra si espandono oltre il limite di lunghezza della riga di comando del sistema.

find . -name . -o -prune -exec rm -rf -- {} +

Potrebbe essere più chiaro rimuovere e ricreare la directory. Ciò ha il vantaggio (o il rovescio della medaglia, a seconda dei casi) di creare una directory vuota anche se un altro programma sta creando contemporaneamente file nella directory originale.


8
Questa dovrebbe essere la risposta accettata, in quanto impedisce l'attraversamento dei genitori e la possibile eliminazione.
rbellamy,

L' findalternativa restituisce "esito positivo" anche se alcuni file non vengono eliminati correttamente; non va bene per la sceneggiatura.
Franklin Yu,

Per quanto riguarda il tuo secondo findcomando, la manpage di find afferma "Poiché -delete implica -depth, non puoi usare utilmente -prune e -delete insieme". - eppure usi -prune -delete?
Doktor J,

@DoktorJ In effetti, -prunenon fa nulla qui. E rileggendo vedo che non ho risposto correttamente alla domanda: mi sono preso cura di non ricorrere, ma la domanda richiede esplicitamente la cancellazione ricorsiva. Ho corretto la mia risposta.
Gilles,

2
@haylem In zsh, è necessario scrivere .[^.]*invece di .[!.]*quando è abilitata la sostituzione della cronologia (che per impostazione predefinita è il caso interattivo ma non negli script), perché zsh analizza !come riferimento della cronologia. Ma in zsh non ti servirà in primo luogo, puoi semplicemente usare *(D)per includere file dot (senza .o ..) nella corrispondenza dei caratteri jolly.
Gilles,

21

Ho appena realizzato che questo è il modo più conveniente nella maggior parte delle distribuzioni Linux:

ls -A1 | xargs rm -rf

dove

-A= elenca tutto tranne . e..

-1 = metti tutti gli articoli in una riga


4
l'aspetto negativo che vedo è: è necessario 'cd' nella directory per fare questo.
Kumar,

ls -A1 /your/path/ | xargs rm -rfdovrebbe applicare
godzillante il

no..it non aiuta - Ad esempio: ls -A1 ~ / test / | xargs rm -rf questo comando cancella i file in cui sono attualmente 'cd in' .. non nella directory ~ / test.
Kumar,

5
Non funziona se uno dei nomi dei file contiene spazi vuoti, nuove righe, virgolette o barre rovesciate.
Stéphane Chazelas,

1
-1 A causa del commento sopra. ↑↑↑↑↑↑↑↑
somethingSomething

15

O cambia l' dotglobopzione della tua shell e usa *, o usa qualcosa di simile find.

find somedir -mindepth 1 -delete

2
Oppure potresti semplicemente rm -rf /some/dircreare una nuova directory vuota al suo posto.
triplo

La migliore opzione finora. Molto sicuro poiché si specifica esplicitamente il percorso della directory.
Yanick Girouard,

4

Questo dovrebbe funzionare proprio come la risposta di @Gilles ma più compatto:

rm -rf {,.[!.],..?}*

o

rm -rf dir/to/files/{,.[!.],..?}*

dovrebbe anche aggiungere un ifper l'utilizzo negli script solo per sicurezza:

if [ -d "$DIR" ]; then
    rm -rf ${DIR}/{,.[!.],..?}*
fi

1
Stranamente, come alias bash su Ubuntu 16.04 LTS, la risposta precedente non funzionava. Tuttavia, lo alias cleandir='rm -rf {,.[!.],..?}*'fa.
Steven Ventimiglia,

3

Trova è tuo amico.

find ! -name '.' ! -name '..' -delete

% find ! -name '.' ! -name '..'
./test
./test4
./test4/.test6
./test3
./.test5
./test2
% find ! -name '.' ! -name '..' -delete    
% find ! -name '.' ! -name '..'     
%             

Se si desidera utilizzare la ricerca ricorsiva di qualcos'altro nella directory corrente ($ PWD), quindi aggiungere un percorso subito dopo il findcomando; ad es find /path ! -name '.' ! -name '..' -delete. Se si desidera solo scendere il nnumero di directory, utilizzare l' -maxdepth nopzione subito dopo il /pathparametro.

Il comando sopra è stato testato su un sistema Ubuntu 13.04. Probabilmente funzionerà su altri sistemi Linux moderni.


per eliminare tutte le directory nella directory corrente che potresti farefind . ! -name '.' ! -name '..' -type d -delete
Andy,

2

Qual è il modo corretto per rimuovere ricorsivamente tutti i file e le cartelle nascosti e non nascosti in una directory di destinazione senza ricevere l'avviso / errore. e ..?

Supponendo che la directory in questione sia ./dir, quindi

rm -rf ./dir

rimuoverebbe tutti i file in ./dir, inclusi file e directory nascosti, in modo ricorsivo e includendo la ./dirdirectory stessa.

Se non si desidera eliminare la directory stessa, è possibile ricrearla in seguito o utilizzare

find ./dir -mindepth 1 -delete

o se findnon supportate -delete,

find ./dir -mindepth 1 -depth -exec rm -rf {} ';'

L'uso -mindepth 1consente di mantenere la directory di livello superiore ./dir.


questa dovrebbe essere contrassegnata come migliore risposta
kitingChris

1

Ti suggerisco di sperimentare

Turn- ON punti (file nascosti)

  • impostato dotglob

    shopt -s dotglob

Turn- OFF puntini

  • non settato dotglob

    shopt -u dotglob

Questo metodo ha funzionato esattamente come desideravo un comando di copia in cui mancavano le directory nascoste.

    shopt -s    dotglob
    cp    -rvn  ./$from/*  ./$too/
    shopt -u    dotglob

Quindi ho fatto una rimozione (eliminazione) e ops ...

    shopt -s    dotglob
    rm -fr ../message_splitter--044a/*
    shopt -u    dotglob

... funziona anche!

Mi viene in mente che si caro lettore, non può vedere la message_splitterdirectory. In ogni modo ha una .svncartella che deve essere rimossa e copiata in.

Dalla manpagina ...

dotglob Se impostato, bash include i nomi di file che iniziano con un `. ' nei risultati dell'espansione del nome percorso.

Riferimenti:


-2

Prova questo codice:

Dirlist=``find /some/path/ -type d -name '.[^.]*'`
for HiddenDir in $Dirlist
do
    rm -rf $HiddenDir
done
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.