Elimina ricorsivamente directory vuote in Windows


94

Ho una directory sulla mia macchina Windows 7 che ha centinaia se non migliaia di sottodirectory. Alcuni di essi hanno file, altri no. Voglio eliminare tutte le directory vuote.

Guardando il comando del e rmdir DOS, non sembra che tu possa farlo in modo ricorsivo senza cancellare tutti i file. C'è un modo per farlo dalla riga di comando?


Sono sorpreso che non ci sia una risposta semplice a questa domanda.
billpg

@billpg: semplice come si potrebbe ottenere: xcopy FROMDIR TODIR /s. Vedere questo SO rispondere: stackoverflow.com/a/14742810
Eckes

1
XCOPY elimina le directory?
billpg

1
Può essere fatto facilmente usando ROBOCOPY. Vedi la mia risposta qui sotto per i dettagli.
Varun Sharma,

Risposte:


116

È possibile utilizzare l' utilità Rimuovi directory vuote .

In alternativa è possibile utilizzare questo file batch di una riga (da DownloadSquad ):

for /f "delims=" %d in ('dir /s /b /ad ^| sort /r') do rd "%d"

(se utilizzato all'interno di un file batch, sostituirlo %dcon %%d)

Questo funziona perché rdnon rimuoverà una directory che contiene file.


6
PS Ti suggerisco di provare prima lo strumento basato sulla GUI, prima di provare qualsiasi comando da riga di comando che può potenzialmente eliminare tutti i file.
Caliban,

1
Assicurati che sia veramente vuoto. Un desktop.ini nascosto è ancora considerato un file. uguale a thumbs.db. Se si desidera verificare se funziona, creare una directory di prova con directory vuote e popolate. Funziona, ho verificato.
Caliban,

1
Sì. Funziona. Errore mio.
EBGreen

8
per / f% d in ('dir / s / b') do rmdir "% d" dovrebbe funzionare poiché rmdir non può rimuovere una cartella non vuota
seanyboy,

1
Guarda stackoverflow.com/a/34025977/694360 per scoprire come aggiungere questa funzionalità al menu di scelta rapida.
mmj

49

Puoi anche usare ROBOCOPY. È molto semplice e può anche essere utilizzato per eliminare cartelle vuote all'interno di una gerarchia di grandi dimensioni.

ROBOCOPY folder1 folder1 /S /MOVE

Qui sono sia l'origine che la destinazione folder1, poiché è sufficiente eliminare le cartelle vuote, invece di spostare altri file in cartelle diverse. /Sl'opzione è di saltare la copia (spostando, nel caso sopra) cartelle vuote. È anche più veloce poiché i file vengono spostati all'interno della stessa unità.


1
Magia. Quindi questo sposta tutte le cartelle non vuote nella stessa posizione in cui si trovavano già (quindi niente?) E salta le cartelle vuote? Ma poi: perché saltarli comporterebbe la cancellazione? E questo non sposterebbe le cartelle nidificate in folder1? Spaventoso, a meno che non sia stato testato bene.
Arjan,

3
@Arjan L'ho provato e funziona perfettamente !. Per capire come funziona, è come spostare tutti i file in posizioni diverse, tranne le cartelle vuote, e quindi eliminare le cartelle vuote lasciate indietro. /MOVEcopia prima i file, quindi elimina il file di origine dopo la copia. Quindi, come /Sviene utilizzato, copia le cartelle non vuote nella destinazione (stessa cartella nel caso precedente). Quindi, elimina le cartelle vuote (come, pensando che le cartelle vuote siano già state copiate). No, non sposta le cartelle nidificate in folder1, poiché ROBOCOPY sposta le cartelle in modo ricorsivo.
Varun Sharma,

3
funziona anche con percorsi UNC (almeno su win7)! Geniale!
Arioch 'Il

2
Questa è una soluzione molto elegante senza bisogno di software di terze parti. Grazie!
Marcus Mangelsdorf,

1
Questo ha appena fatto la sua magia e ha funzionato perfettamente. Grazie!
CharleyDC5,

15

Poiché Cygwin viene fornito con GNU find, puoi farlo:

find . -type d -empty -delete

O per evitare il rumore quando non esiste più una cartella:

find . -type d -empty -execdir rmdir {} +

Questo ora può anche essere fatto usando Windows 10 Bash.
Marzo Ho

Per la mia installazione di Windows 10 questo ( find . -type d -empty -delete) non riesce dal prompt dei comandi con il seguente errore:FIND: Parameter format not correct
ImpressTheNet Web Developer

7

L'utilità gratuita EmptyFolderNuker fa questo bene, da una cartella di base di tua scelta. Rimuove anche quelle directory che contengono solo sottodirectory vuote.


1
Il file batch one-liner non ha funzionato per me (viene visualizzato l'errore "%% d era imprevisto in questo momento.") E il programma Rimuovi directory vuote non verrà installato (si dice sulla pagina collegata che non lo è compatibile con Windows 7 comunque). Questo programma ha funzionato come un fascino.
Phoenix,

1
Come ha scritto user36580 di seguito, "è probabile che tu stia eseguendo direttamente dalla riga di comando. In tal caso, modifica il doppio %% in un singolo%"
Lachlan McD.

1
Mi piace sulla versione da riga di comando pura in quanto ti consente di visualizzare in anteprima le cose che vengono eliminate. Puoi sempre chiamarlo dalla riga di comando usando "%~dp0\EmptyFolderNuker.exe" %cd%.
Jeroen Wiert Pluimers,

1
@ rob-kam L'URL per "EmptyFolderNuker" non è più disponibile.
PeterCo

@PeterCo Grazie, risolto ora.
Rob Kam,

0

Se hai installato Cygwin , puoi farlo:

find -type d -exec rmdir {} \;

4
Non necessariamente. Ciò potrebbe non eliminare le directory con solo sottodirectory vuote. Potrebbe essere necessario invertirlo. find -type d -print0 | tac | xargs -0 rmdir
Ryan Thompson,

Non ho mai saputo di "tac" prima. È davvero elegante!
Anthony Giorgio,

1
Oppure usa . L' opzione dice di fare qualcosa come invertire l'ordine dell'output: va prima ai livelli di directory più profondi, quindi torna indietro. find (starting-directory) -depth -type d ...-depthfind
G-Man,

0

Se lavori in emacs (rendendo questa piattaforma indipendente), il seguente funziona:

(defun *-delete-empty-directories (root-directory)
  "Recursively delete empty directories in ROOT-DIRECTORY.

When called from dired, `dired-current-directory' is used for
ROOT-DIRECTORY."

  ;; Interface
  (interactive (list (if (eq major-mode 'dired-mode)
                         (expand-file-name (dired-current-directory))
                       (read-from-minibuffer "Root directory: "))))
  (when (or (null root-directory) (string= "" root-directory))
    (user-error "No root directory provided"))
  (when (called-interactively-p 'interactive)
    (unless (yes-or-no-p (format "Delete all non-empty directories in `%s'? "
                                 root-directory))
      (user-error "Directory `%s' has been left untouched" root-directory)))

  ;; Implementation
  (require 'f)
  (let ((entries (f-directories root-directory)))
    (while entries
      (let ((curdir (car entries)))
        (when (f-directories curdir)
          (*-delete-empty-directories curdir))
        (unless (f-entries curdir)
          (delete-directory curdir)
          (message "Directory deleted: `%s'" curdir))
        (setq entries (cdr entries)))))

... Per favore, dimmi che non dovresti digitare tutto questo per farlo in emacs.
Hashim,

1
@Hashim L'idea è di averlo definito nel tuo init e quindi associato a una chiave. Tecnicamente avrei potuto vincolarlo Dse avessi voluto, ma poiché non ho un bisogno comune per questo, tutto ciò che devo scrivere è M-x *ded RETe bam-done. (Se davvero dovessi scrivere questo ogni volta, hai assolutamente ragione che sarebbe assurdo - per fortuna non è così.)
Sean Allred

Abbastanza giusto, sembra più plausibile.
Hashim,

Non M-x *ded REThanno alcun significato o è casuale? In quest'ultimo caso, come tenere traccia di tutte le scorciatoie assegnate emacs? La memorizzazione è sufficiente o ti ritrovi a doverli cercare?
Hashim,

1
@Hashim *dedè un'abbreviazione per il nome completo della funzione *-delete-empty-directories. Molti motori di completamento (come l'edera, quello che uso) comprendono questo tipo di corrispondenza fuzzy. Per quanto riguarda tenerli memorizzati ... Semplicemente non devo. Le funzioni che ho definito iniziano tutte in *modo da poterle facilmente trovare se non sono associate a una chiave. Altrimenti, emacs stesso mi dirà se c'era un modo più veloce di chiamare la funzione. Se tutto il resto fallisce, c'è sempre apropos.
Sean Allred,

0

Combinando i post di Gareth e G-Man:

find . -depth -type d -empty -execdir rmdir {} +

Modifica: Ma questo ha dato un errore di sicurezza a causa di 'C' nel mio var PATH ... quindi invece:

$find . -depth -type d -empty | while read dir; do (rmdir -v $dir); done

Non uso xargs perché sembra avere un limite di input line (di circa 1024 righe, penso?), Mentre

 while read x; do (command $x); done

continua solo finché ha input. Escludere il flag dettagliato '-v' se non si desidera vedere i risultati e / o si desidera che esegua più velocemente.


0

Hmmm ... forse anche la soluzione più semplice:

for /d /r %d in (*.*) do rd "%d"

Inizia questo dalla cartella in cui desideri eliminare le cartelle vuote.

/ d - funzionerà su cartelle, non su file / r - richiamerà i sottodir

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.