Xóa đệ quy các thư mục trống trong Windows


93

Tôi có một thư mục trên máy Windows 7 của mình có hàng trăm nếu không phải là hàng ngàn thư mục con. Một số trong số họ có tập tin, một số thì không. Tôi muốn xóa tất cả các thư mục trống.

Nhìn vào lệnh del và rmdir DOS, có vẻ như bạn không thể đệ quy làm điều này mà không xóa tất cả các tệp. Có cách nào để làm điều này từ dòng lệnh?


Tôi ngạc nhiên không có câu trả lời đơn giản cho câu hỏi này.
billpg

@billpg: đơn giản như nó có thể nhận được : xcopy FROMDIR TODIR /s. Xem câu trả lời SO này: stackoverflow.com/a/14742810
eckes 20/03 '

1
XCOPY xóa thư mục?
billpg 20/03/13

1
Nó có thể được thực hiện dễ dàng bằng ROBOCOPY. Xem câu trả lời của tôi dưới đây để biết chi tiết.
Varun Sharma

Câu trả lời:


115

Bạn có thể sử dụng tiện ích Remove Empty Directories .

Ngoài ra, bạn có thể sử dụng tệp bó một lớp này (từ DownloadSquad ):

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

(nếu được sử dụng trong một tệp bó, thay thế %dbằng %%d)

Điều này hoạt động bởi vì rdsẽ không loại bỏ một thư mục có chứa các tập tin.


6
PS Tôi khuyên bạn nên thử công cụ dựa trên GUI trước, trước khi thử bất kỳ lệnh dòng lệnh nào có khả năng xóa tất cả các tệp.
caliban

1
Hãy chắc chắn rằng nó thực sự trống rỗng. Một desktop.ini ẩn vẫn được coi là một tập tin. giống như ngón tay cái.db. Nếu bạn muốn xác minh xem điều này có hoạt động hay không, hãy tạo một thư mục thử nghiệm với các thư mục bên trong trống và được điền. Nó hoạt động, tôi đã xác minh.
caliban

1
Vâng. Nó hoạt động. Lỗi của tôi.
EBGreen

8
for / f% d in ('dir / s / b') do rmdir "% d" nên hoạt động vì rmdir không thể xóa thư mục không trống
seanyboy

1
Nhìn vào stackoverflow.com/a/34025977/694360 để tìm hiểu cách thêm chức năng này vào menu ngữ cảnh.
mmj

49

Bạn cũng có thể sử dụng ROBOCOPY. Nó rất đơn giản và cũng có thể được sử dụng để xóa các thư mục trống trong hệ thống phân cấp lớn.

ROBOCOPY folder1 folder1 /S /MOVE

Ở đây cả nguồn và đích là folder1, vì bạn chỉ cần xóa các thư mục trống, thay vì di chuyển các tệp khác sang thư mục khác. /Stùy chọn là bỏ qua việc sao chép (di chuyển, trong trường hợp trên) các thư mục trống. Nó cũng nhanh hơn khi các tệp được di chuyển trong cùng một ổ đĩa.


1
Ma thuật. Vì vậy, điều này di chuyển tất cả các thư mục không trống đến cùng một vị trí mà chúng đã ở (vậy có gì không?) Và bỏ qua các thư mục trống? Nhưng sau đó: tại sao bỏ qua chúng sẽ dẫn đến xóa? Và điều này sẽ không di chuyển các thư mục lồng nhau vào folder1? Đáng sợ, trừ khi thử nghiệm tốt.
Arjan

3
@Arjan Tôi đã thử nó, và nó hoạt động hoàn hảo!. Để hiểu hoạt động của nó, nó giống như di chuyển tất cả các tệp đến vị trí khác nhau, ngoại trừ các thư mục trống, sau đó xóa các thư mục trống phía sau bên trái. /MOVEsao chép các tệp trước, sau đó xóa tệp nguồn sau khi sao chép. Vì vậy, như /Sđược sử dụng, nó sao chép các thư mục không trống vào đích (cùng thư mục trong trường hợp trên). Sau đó, nó xóa các thư mục trống (như, nó nghĩ rằng các thư mục trống đã được sao chép). Không, nó không di chuyển các thư mục lồng nhau vào folder1, vì ROBOCOPY di chuyển các thư mục theo cách đệ quy.
Varun Sharma

3
nó thậm chí hoạt động với các đường dẫn UNC (ít nhất là trên win7)! Xuất sắc !
Arioch '

2
Đây là một giải pháp rất thanh lịch mà không cần bất kỳ phần mềm của bên thứ ba nào. Cảm ơn bạn!
Marcus Mangelsdorf

1
Điều này chỉ làm điều kỳ diệu của nó và làm việc hoàn hảo. Cảm ơn!
CharleyDC5

15

Vì Cygwin đi kèm với GNU find, bạn có thể làm điều này:

find . -type d -empty -delete

Hoặc để tránh tiếng ồn khi thư mục không còn tồn tại:

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

Điều này cũng có thể được thực hiện bằng Windows 10 Bash.
Hồ tháng 3 ngày

Đối với cài đặt Windows 10 của tôi, điều này ( find . -type d -empty -delete) không thành công từ dấu nhắc lệnh với lỗi sau:FIND: Parameter format not correct
ImpressTheNet Web Developer

7

Tiện ích miễn phí EmptyFolderNuker thực hiện tốt điều này, từ một thư mục cơ sở bạn chọn. Nó cũng loại bỏ các thư mục chỉ chứa các thư mục con trống.


1
Tệp bó một lớp không hoạt động đối với tôi (tôi gặp lỗi "%% d không mong đợi tại thời điểm này.") Và chương trình Xóa thư mục trống sẽ không cài đặt (thông báo trên trang được liên kết rằng nó không phải là vẫn tương thích với Windows 7). Chương trình này hoạt động như một cơ duyên.
Phượng hoàng

1
Như user36580 đã viết dưới đây, "có khả năng bạn đang chạy trực tiếp từ dòng lệnh. Trong trường hợp đó, hãy thay đổi %% thành một%"
Lachlan McD.

1
Tôi thích điều này hơn phiên bản dòng lệnh thuần túy vì nó cho phép bạn xem trước những thứ bị xóa. Bạn luôn có thể gọi nó từ dòng lệnh bằng cách sử dụng "%~dp0\EmptyFolderNuker.exe" %cd%.
Jeroen Wiert Pluimers

1
@ rob-kam URL cho "EmptyFolderNuker" không còn khả dụng nữa.
PeterCo

@PeterCo Cảm ơn, đã sửa ngay.
Rob Kam

0

Nếu bạn đã cài đặt Cygwin , bạn có thể làm điều này:

find -type d -exec rmdir {} \;

4
Không cần thiết. Điều đó có thể không xóa các thư mục chỉ có các thư mục con trống. Bạn có thể phải đảo ngược nó. tìm -type d -print0 | tấc | xargs -0 rmdir
Ryan Thompson

Tôi chưa bao giờ biết về "tac" trước đây. Điều đó thực sự tiện lợi!
Anthony Giorgio

1
Hoặc sử dụng . Các tùy chọn nói để làm một cái gì đó giống như đảo ngược thứ tự của đầu ra - nó đi đến cấp độ thư mục sâu nhất đầu tiên, sau đó làm việc theo cách của mình trở lại. find (starting-directory) -depth -type d ...-depthfind
G-Man

0

Nếu bạn đang làm việc trong emacs (tạo ra nền tảng bất khả tri này), các công việc sau:

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

... Xin vui lòng cho tôi biết bạn sẽ không phải gõ tất cả những điều này để thực hiện điều này trong emacs.
Hashim

1
@Hashim Ý tưởng là bạn đã xác định nó trong init của mình và sau đó ràng buộc với một khóa. Về mặt kỹ thuật tôi có thể bị ràng buộc Dnếu tôi muốn, nhưng vì tôi không có nhu cầu chung cho việc này, nên tất cả những gì tôi phải gõ là M-x *ded RETvà thực hiện. (Nếu tôi thực sự phải gõ cái này mỗi lần, bạn hoàn toàn đúng rằng nó sẽ vô lý - may mắn là không phải vậy.)
Sean Allred

Đủ công bằng, điều đó nghe có vẻ hợp lý hơn.
Hashim

M-x *ded RETbất kỳ ý nghĩa hay là ngẫu nhiên? Nếu sau này, làm thế nào để bạn theo dõi tất cả các phím tắt bạn đã gán emacs? Có phải việc ghi nhớ đủ hay bạn thấy mình phải tìm kiếm chúng?
Hashim

1
@Hashim *dedlà tên viết tắt của tên hàm đầy đủ *-delete-empty-directories. Nhiều công cụ hoàn thành (như ivy, cái tôi sử dụng) hiểu loại kết hợp mờ này. Đối với việc giữ cho họ ghi nhớ, tôi chỉ đơn giản là không phải. Các chức năng tôi đã xác định bắt đầu bằng tất cả *để tôi có thể dễ dàng tìm thấy chúng nếu chúng không bị ràng buộc với khóa. Nếu không, emacs sẽ cho tôi biết nếu có cách gọi hàm nhanh hơn. Nếu thất bại, luôn luôn có apropos.
Sean Allred

0

Kết hợp các bài đăng của Gareth và G-Man:

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

Chỉnh sửa: Nhưng điều đó đã gây ra lỗi bảo mật vì 'C' trong var PATH của tôi ... vì vậy thay vào đó:

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

Tôi không sử dụng xargs vì nó dường như có giới hạn dòng đầu vào (khoảng 1024 dòng, tôi nghĩ vậy?), Trong khi đó

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

chỉ cần tiếp tục miễn là nó có đầu vào. Bỏ cờ dài dòng '-v' nếu bạn không muốn xem kết quả và / hoặc muốn nó chạy nhanh hơn.


0

Hmmm ... có thể là giải pháp đơn giản hơn:

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

Bắt đầu điều này từ thư mục bạn muốn xóa các thư mục trống.

/ d - sẽ hoạt động trên các thư mục, không phải tệp / r - sẽ lặp lại các thư mục con

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.