Supprimer récursivement les répertoires vides dans Windows


94

J'ai un répertoire sur ma machine Windows 7 qui a des centaines voire des milliers de sous-répertoires. Certains d'entre eux ont des fichiers, d'autres pas. Je veux supprimer tous les répertoires vides.

En regardant les commandes DOS del et rmdir, il ne semble pas que vous puissiez le faire récursivement sans supprimer tous les fichiers. Y a-t-il un moyen de faire cela depuis la ligne de commande?


Je suis étonné qu'il n'y ait pas de réponse simple à cette question.
billpg

@billpg: simple qu'il pourrait obtenir: xcopy FROMDIR TODIR /s. Voir cette réponse SO: stackoverflow.com/a/14742810
eckes

1
XCOPY supprime les répertoires?
billpg

1
Cela peut être fait facilement avec ROBOCOPY. Voir ma réponse ci-dessous pour plus de détails.
Varun Sharma

Réponses:


116

Vous pouvez utiliser l' utilitaire Supprimer les répertoires vides .

Sinon, vous pouvez utiliser ce fichier de commandes one-liner (à partir de DownloadSquad ):

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

(si utilisé dans un fichier batch, remplacer %dpar %%d)

Cela fonctionne car rdne supprimera pas un répertoire contenant des fichiers.


6
Post-scriptum Je suggère que vous essayez d'abord l'outil basé sur une interface graphique, avant d'essayer toutes les commandes de ligne de commande qui peuvent potentiellement supprimer tous les fichiers.
Caliban

1
Assurez-vous qu'il est vraiment vide. Un desktop.ini caché est toujours considéré comme un fichier. comme un thumbs.db. Si vous voulez vérifier si cela fonctionne, créez un répertoire de test contenant des répertoires vides et remplis. Ça marche, j'ai vérifié.
Caliban

1
Oui. Ça marche. Mon erreur.
EBGreen

8
pour / f% d dans ('dir / s / b') do rmdir "% d" devrait fonctionner car rmdir ne peut pas supprimer un dossier non vide
seanyboy le

1
Regardez stackoverflow.com/a/34025977/694360 pour savoir comment ajouter cette fonctionnalité au menu contextuel.
mmj

49

Vous pouvez également utiliser ROBOCOPY. Il est très simple et peut également être utilisé pour supprimer des dossiers vides dans une grande hiérarchie.

ROBOCOPY folder1 folder1 /S /MOVE

Ici, les sources et les destinations sont folder1, car il vous suffit de supprimer des dossiers vides, au lieu de déplacer d'autres fichiers dans un autre dossier. /SL’option consiste à ignorer la copie (déplacement, dans le cas ci-dessus) de dossiers vides. Il est également plus rapide car les fichiers sont déplacés dans le même lecteur.


1
La magie. Ainsi, tous les dossiers non vides sont déplacés vers le même emplacement où ils se trouvaient déjà (et rien d'autre?) Et les dossiers vides sont ignorés. Mais alors: pourquoi les ignorer entraînerait-il une suppression? Et cela ne déplacerait-il pas les dossiers imbriqués folder1? Effrayant, sauf si bien testé.
Arjan le

3
@Arjan je l'ai testé et il fonctionne parfaitement !. Pour comprendre son fonctionnement, il s’agit de déplacer tous les fichiers vers un emplacement différent, à l’exception des dossiers vides, puis de supprimer les dossiers vides laissés. /MOVEcopie d’abord les fichiers, puis supprime le fichier source après la copie. Ainsi, comme il /Sest utilisé, il copie les dossiers non vides vers la destination (même dossier dans le cas ci-dessus). Ensuite, il supprime les dossiers vides (par exemple, il pense que les dossiers vides ont déjà été copiés). Non, il ne déplace pas les dossiers imbriqués folder1, car ROBOCOPY les déplace de manière récursive.
Varun Sharma

3
cela fonctionne même avec les chemins UNC (au moins sur win7)! Brillant !
Arioch 'Le

2
C'est une solution très élégante sans logiciel tiers requis. Je vous remercie!
Marcus Mangelsdorf

1
Cela a juste fait sa magie et a fonctionné parfaitement. Merci!
CharleyDC5 le

15

Puisque Cygwin est fourni avec GNU find, vous pouvez le faire:

find . -type d -empty -delete

Ou pour éviter le bruit lorsqu'un dossier n'existe plus:

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

Cela peut aussi maintenant être fait avec Windows 10 Bash.
Mars Ho

Pour mon installation de Windows 10, this ( find . -type d -empty -delete) échoue à partir de l'invite de commande avec l'erreur suivante:FIND: Parameter format not correct
ImpressTheNet Web Developer

7

L'utilitaire gratuit EmptyFolderNuker fait très bien l' affaire , à partir du dossier de base de votre choix. Il supprime également les répertoires contenant uniquement des sous-répertoires vides.


1
Le fichier batch one-liner ne fonctionnait pas pour moi (le message d'erreur "%% d était inattendu à ce moment-là"), et le programme Supprimer les répertoires vides ne s'installera pas compatible avec Windows 7 en tout cas). Ce programme a fonctionné comme un charme.
Phoenix

1
Comme l’a écrit l’utilisateur 36580 ci-dessous, "il est probable que vous exécutez directement à partir de la ligne de commande. Dans ce cas, remplacez le double %% par un simple%"
Lachlan McD.

1
J'aime cela sur la version en ligne de commande pure, car elle vous permet de prévisualiser les éléments supprimés. Vous pouvez toujours l'appeler depuis la ligne de commande en utilisant "%~dp0\EmptyFolderNuker.exe" %cd%.
Jeroen Wiert Pluimers

1
@ rob-kam L'URL de "EmptyFolderNuker" n'est plus disponible.
PeterCo

@PeterCo Merci, corrigé maintenant.
Rob Kam

0

Si vous avez installé Cygwin , vous pouvez faire ceci:

find -type d -exec rmdir {} \;

4
Pas nécessairement. Cela pourrait ne pas supprimer les répertoires contenant uniquement des sous-répertoires vides. Vous devrez peut-être l'inverser. trouver -type d -print0 | tac | xargs -0rmdir
Ryan Thompson

Je n'avais jamais entendu parler de "tac" auparavant. C'est vraiment chouette!
Anthony Giorgio

1
Ou utiliser . L' option indique de faire quelque chose comme inverser l'ordre de la sortie: elle passe en premier aux niveaux de répertoire les plus profonds, puis fonctionne à nouveau. find (starting-directory) -depth -type d ...-depthfind
G-Man

0

Si vous travaillez dans emacs (ce qui rend cette plate-forme agnostique), les opérations suivantes fonctionnent:

(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)))))

... S'il vous plaît, dites-moi que vous n'auriez pas à taper tout cela pour pouvoir le faire dans emacs.
Hashim

1
@Hashim L'idée est que vous l'avez défini dans votre init puis lié à une clé. Techniquement, je pourrais l'avoir lié Dsi je le voulais, mais comme je n'ai pas de besoin commun pour cela, tout ce que je dois taper est M-x *ded RETet bam-done. (Si je devais effectivement taper ce texte à chaque fois, vous avez absolument raison. Ce serait absurde. Heureusement, ce n'est pas le cas.)
Sean Allred, le

Assez juste, cela semble plus plausible.
Hashim

Cela M-x *ded RETa- t -il une signification ou est-ce aléatoire? Dans ce dernier cas, comment gardez-vous une trace de tous les raccourcis que vous avez attribués emacs? La mémorisation suffit-elle ou vous trouvez-vous obligé de les rechercher?
Hashim

1
@Hashim *dedest une abréviation du nom complet de la fonction *-delete-empty-directories. De nombreux moteurs de complétion (tels que ivy, celui que j'utilise) comprennent ce type de correspondance floue. Pour ce qui est de les garder mémorisés… je n'ai tout simplement pas à le faire. Les fonctions que j'ai définies commencent par toutes *afin que je puisse les retrouver facilement si elles ne sont pas liées à une clé. Sinon, Emacs lui-même me dira s'il y avait un moyen plus rapide d'appeler la fonction. Si tout échoue, il y a toujours apropos.
Sean Allred

0

Combinaison des messages de Gareth et de G-Man:

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

Edit: Mais cela a donné une erreur de sécurité à cause de 'C' dans mon PATH var ... donc à la place:

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

Je n’utilise pas xargs car il semble y avoir une limite de lignes en entrée (environ 1024 lignes, je pense?), Alors que

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

continue à aller aussi longtemps qu'il a son mot à dire. Si vous ne voulez pas voir les résultats et / ou si vous voulez que les résultats soient plus rapides, laissez l'indicateur verbose '-v'.


0

Hmmm ... peut-être même une solution plus simple:

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

Commencez par le dossier où vous voulez que les dossiers vides soient supprimés.

/ d - travaillera sur les dossiers, pas les fichiers / r - recurse les sous-répertoires

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.