86

У меня есть каталог на моем компьютере с Windows 7, в котором есть сотни, если не тысячи подкаталогов. У некоторых из них есть файлы, у некоторых нет. Я хочу удалить все пустые каталоги.

Глядя на команду del и rmdir DOS, не похоже, что вы можете сделать это рекурсивно, не удаляя все файлы. Есть ли способ сделать это из командной строки?

9 ответов9

105

Вы можете использовать утилиту удаления пустых каталогов .

В качестве альтернативы вы можете использовать этот однострочный пакетный файл (из DownloadSquad):

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

(если используется внутри пакетного файла, замените %d на %%d)

Это работает, потому что rd не удалит каталог, содержащий файлы.

39

Вы также можете использовать ROBOCOPY. Это очень просто и может также использоваться для удаления пустых папок внутри большой иерархии.

ROBOCOPY folder1 folder1 /S /MOVE

Здесь и источник, и пункт назначения - это folder1 , так как вам нужно только удалить пустые папки, а не перемещать другие файлы в другую папку. /S пропускает копирование (перемещение, в вышеописанном случае) пустых папок. Это также быстрее, поскольку файлы перемещаются внутри одного диска.

15

Так как Cygwin поставляется с GNU find, вы можете сделать это:

find . -type d -empty -delete

Или чтобы избежать шума, когда папка больше не существует:

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

Бесплатная утилита EmptyFolderNuker делает это нормально из базовой папки на ваш выбор. Также удаляются те каталоги, которые содержат только пустые подкаталоги.

1

У отличных утилит Glary есть это и множество других замечательных функций.

0

Если вы работаете в emacs (что делает эту платформу независимой), работает следующее:

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

Хм ... может быть, даже более простое решение:

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

Запустите это из папки, в которую вы хотите удалить пустые папки.

/d - будет работать с папками, а не с файлами /r - будет возвращать подкаталоги

0

Объединение сообщений Гарета и G-Man:

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

Редактировать: Но это дало ошибку безопасности из-за 'C' в моей переменной PATH ... поэтому вместо этого:

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

Я не использую xargs, потому что кажется, что он имеет ограничение входной строки (около 1024 строк, я думаю?), Тогда как

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

просто продолжается до тех пор, пока у него есть вход. Оставьте подробный флаг '-v', если вы не хотите видеть результаты и / или хотите, чтобы он работал быстрее.

0

Если у вас установлен Cygwin , вы можете сделать это:

find -type d -exec rmdir {} \;

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .