Cách xóa số lượng lớn tệp trên Windows


22

Tôi có một thư mục chứa hàng triệu thư mục con và hàng nghìn tỷ tệp. Và bây giờ tôi phải xóa nó. Nói về nghìn tỷ, tôi không nói về kích thước tệp, nhưng số lượng tệp.

Tôi đã thử xóa nó bằng del/svà sử dụng Windows Explorer. Không thể hoàn thành nhiệm vụ. Tôi đã cố gắng xóa từng thư mục con từng cái một và điều đó khiến tôi mất nhiều ngày. Vấn đề tôi gặp là mỗi lần, bất kể sử dụng delhay Explorer, tôi đều có thể thấy trong Trình quản lý tác vụ rằng phiên bản thám hiểm tiêu thụ bộ nhớ trên trời và dần dần đẩy hệ thống của tôi gặp sự cố.

Vẫn còn vài trăm triệu tập tin sẽ bị xóa. Có bất kỳ khả năng nào để đạt được với một (hoặc chỉ một vài) lệnh / hành động không?


[EDITED]

Tôi đã thử làm điều đó với Cygwin rm -frvà cho kết quả tương tự. Tóm tắt là:

  1. Bất kể sử dụng Windows Explorer, DELtừ dấu nhắc lệnh hoặc rmlệnh Cygwin , bộ nhớ Hệ thống giảm dần về 0 và hộp cuối cùng sẽ sụp đổ.

  2. Nếu tại bất kỳ thời điểm nào, trước khi hệ thống bị lỗi, quy trình được đóng lại (bằng CTRL + C hoặc những gì khác), hộp sẽ tiếp tục hoạt động như bình thường. Tuy nhiên, tất cả bộ nhớ đã sử dụng sẽ KHÔNG được giải phóng. Giả sử, tôi đã dừng quá trình trong khi bộ nhớ hệ thống đạt 91%, Trình quản lý tác vụ cho biết: Tổng số RAM 4G, Cache là 329M và Có sẵn 335 MB. Sau đó, việc sử dụng bộ nhớ sẽ ở quanh mức này cho đến khi tôi khởi động lại máy. Nếu tôi dừng phiên bản thám hiểm trong Trình quản lý tác vụ, màn hình sẽ trống với đèn HDD mọi lúc và không bao giờ quay lại. Thông thường, khi tôi dừng phiên bản thám hiểm trong Trình quản lý tác vụ, tôi có thể gọi lại bằng cách nhấn Win + E hoặc tự động được khởi động lại.

Vâng, quản lý bộ nhớ thực sự tốt đẹp!


[EDIT AGAIN] Có vẻ như một số bộ nhớ đã sử dụng đã được giải phóng sau một thời gian dài, nhưng không phải tất cả. Một số bộ nhớ đã lưu và có sẵn đã quay trở lại trong Trình quản lý tác vụ. Tôi đã không chờ đợi lâu hơn nữa, không chắc điều gì sẽ xảy ra sau đó.


Vì vậy, vấn đề chính của bạn là thực tế là các thư mục và thư mục con không bị xóa?
Sandeep Bansal

@Jackey Cheung: phiên bản windows nào bạn đang sử dụng?
Siva Charan

1
Bạn có thể viết một tập lệnh bó mà xóa các tệp theo cách định kỳ, không bắt đầu từ cấp cao nhất mà trên cấp thứ năm của cấu trúc thư mục. Điều đó sẽ phân chia công việc thành nhiều phần riêng biệt và tuần tự

9
Tôi phải biết, làm thế quái nào bạn có được một nghìn tỷ tập tin, thực sự ...
Moab

2
Một nghìn tỷ tệp cần một bảng tệp là 1 PB. Các đĩa cứng lớn nhất hiện nay là một vài TB. Làm thế nào bạn có thể có được một phân vùng lớn?
Mehrdad

Câu trả lời:


10

Giải thích kỹ thuật

Lý do mà hầu hết các phương pháp đang gây ra vấn đề là Windows cố gắng liệt kê các tệp và thư mục. Đây không phải là vấn đề với vài trăm tập tin hoặc thậm chí hàng nghìn tập tin sâu ở một vài cấp độ sâu, nhưng khi bạn có hàng nghìn tỷ tập tin trong hàng triệu thư mục đi sâu hàng chục cấp, thì điều đó chắc chắn sẽ làm hỏng hệ thống .

Giả sử bạn chỉ có 100.000.000 tập tin và Windows sử dụng một cấu trúc đơn giản như thế này để lưu trữ từng tệp cùng với đường dẫn của nó (theo cách đó bạn tránh lưu trữ từng thư mục riêng biệt, do đó tiết kiệm được một số chi phí):

struct FILELIST {                   // Total size is 264 to 528 bytes:
  TCHAR         name[MAX_PATH];     // MAX_PATH=260; TCHAR=1 or 2 bytes
  FILELIST*     nextfile;           // Pointers are 4 bytes for 32-bit and 8 for 64-bit
}

Tùy thuộc vào việc nó sử dụng các ký tự 8 bit hay ký tự Unicode (nó sử dụng Unicode) và hệ thống của bạn là 32 bit hay 64 bit, thì nó sẽ cần từ 25 GB đến 49 GB bộ nhớ để lưu danh sách (và đây là một cấu trúc đơn giản hóa).

Lý do tại sao Windows cố gắng liệt kê các tệp và thư mục trước khi xóa chúng khác nhau tùy thuộc vào phương pháp bạn đang sử dụng để xóa chúng, nhưng cả Explorer và trình thông dịch lệnh đều làm điều đó (bạn có thể thấy độ trễ khi bạn khởi tạo lệnh). Bạn cũng có thể thấy đèn flash hoạt động của đĩa (HDD LED) khi nó đọc cây thư mục từ ổ đĩa.

Giải pháp

Đặt cược tốt nhất của bạn để đối phó với loại tình huống này là sử dụng một công cụ xóa để xóa từng tệp và thư mục một lần. Tôi không biết nếu có bất kỳ công cụ làm sẵn để làm điều đó, nhưng nó nên có thể thực hiện với một lô-file đơn giản.

@echo off
if not [%1]==[] cd /d %1
del /q *
for /d %%i in (*) do call %0 "%%i"

Điều này làm là để kiểm tra nếu một đối số đã được thông qua. Nếu vậy, nó sẽ thay đổi thư mục được chỉ định (bạn có thể chạy nó mà không cần đối số để bắt đầu trong thư mục hiện tại hoặc chỉ định một thư mục, ngay cả trên một ổ đĩa khác để bắt đầu ở đó).

Tiếp theo, nó xóa tất cả các tập tin trong thư mục hiện tại. Trong chế độ này, nó không nên liệt kê bất cứ thứ gì và chỉ cần xóa các tệp mà không chiếm nhiều bộ nhớ, nếu có ,.

Sau đó, nó liệt kê các thư mục trong thư mục hiện tại và tự gọi nó, chuyển từng thư mục cho nó (tự) để lặp lại xuống dưới.

Phân tích

Lý do mà điều này nên hoạt động là vì nó không liệt kê từng tệp và thư mục trong toàn bộ cây . Nó không liệt kê bất kỳ tập tin nào cả, và chỉ liệt kê các thư mục trong thư mục hiện tại (cộng với các thư mục còn lại trong thư mục mẹ). Giả sử chỉ có vài trăm thư mục con trong bất kỳ thư mục đã cho nào, thì điều này không quá tệ và chắc chắn cần ít bộ nhớ hơn các phương thức khác liệt kê toàn bộ cây.

Bạn có thể tự hỏi về việc sử dụng công /rtắc thay vì sử dụng đệ quy (thủ công). Điều đó sẽ không hoạt động bởi vì trong khi /rchuyển đổi không đệ quy, nó liệt kê trước toàn bộ cây thư mục chính xác là những gì chúng ta muốn tránh; chúng tôi muốn xóa khi chúng tôi đi mà không theo dõi.

So sánh

Hãy so sánh phương pháp này với (các) phương pháp liệt kê đầy đủ.

Bạn đã nói rằng bạn đã có hàng triệu thư mục. Hãy nói 100 triệu. Nếu cây gần như cân bằng và giả sử trung bình khoảng 100 thư mục con trên mỗi thư mục, thì thư mục lồng nhau sâu nhất sẽ có khoảng bốn cấp xuống trên thực tế, sẽ có 101.010.100 thư mục con trong toàn bộ cây. (Giải thích làm thế nào 100M có thể phá vỡ chỉ còn 100 và 4.)

Vì chúng tôi không liệt kê các tệp, chúng tôi chỉ cần theo dõi tối đa 100 tên thư mục cho mỗi cấp độ, cho tối đa các 4 × 100 = 400thư mục tại bất kỳ thời điểm nào.

Do đó, yêu cầu bộ nhớ phải là ~ 206,25KB, trong giới hạn của bất kỳ hệ thống hiện đại (hoặc mặt nào khác).

Kiểm tra

Thật không may (?) Tôi không có một hệ thống với hàng nghìn tỷ tệp trong hàng triệu thư mục, vì vậy tôi không thể kiểm tra được (tôi tin ở lần đếm cuối cùng, tôi có khoảng ~ 800 nghìn tệp), vì vậy người khác sẽ phải thử nó

Hãy cẩn thận

Tất nhiên bộ nhớ không phải là giới hạn duy nhất. Ổ đĩa cũng sẽ là một nút cổ chai lớn bởi vì đối với mỗi tệp và thư mục bạn xóa, hệ thống phải đánh dấu nó là miễn phí. Rất may, nhiều thao tác trên đĩa này sẽ được gói lại với nhau (được lưu trong bộ nhớ cache) và được viết ra thành từng khối thay vì riêng lẻ (ít nhất là cho các ổ đĩa cứng, không phải cho phương tiện lưu động), nhưng nó vẫn sẽ gây ra một chút lỗi khi hệ thống đọc và ghi dữ liệu.


Tôi khá chắc chắn rằng điều này không hoạt động. Tôi đã thử nó. Vấn đề nằm ở vòng lặp FOR. Hóa ra FOR sẽ gây ra vấn đề tương tự như phát hành DEL trực tiếp.
Jackey Cheung

1
Nó phụ thuộc vào các công tắc bạn sử dụng. Nếu bạn đã sử dụng công /rtắc, thì như tôi đã giải thích, nó sẽ cố gắng liệt kê tất cả các tệp. Nếu bạn sử dụng /dkhóa chuyển, nó chỉ liệt kê các thư mục trong thư mục hiện tại, vì vậy trừ khi bạn có một tỷ thư mục trong thư mục hiện tại, nó không gây ra sự cố.
Synetech

7

Tôi không thể nói với hàng nghìn tỷ tệp, nhưng gần đây tôi đã thu được một chia sẻ tệp cũ chứa ~ 1,8 triệu tệp bằng cách sử dụng:

robocopy EmptyTMPFolder FolderToDelete /MIR /MT:16 /ETA /R:30 /W:5

"EmptyTMPFolder" là một thư mục cục bộ trống. tùy chọn / MIR sẽ làm cho mục tiêu trông giống như nguồn (trống).

Lợi ích thực sự cho phương pháp này là tùy chọn thử lại (/ R: 30). Điều này cho phép một cơ hội để hấp thụ bất kỳ vấn đề kết nối nào có thể xảy ra trong quá trình này. Xóa địa phương có thể không tìm thấy lợi ích trong phương pháp này.

Tôi không có điểm chuẩn cụ thể để so sánh thời gian, nhưng tôi thích điều này hơn một số tùy chọn khác được đề xuất b / c của các tùy chọn thử lại / chờ. Các xóa đã bắt đầu gần ngay lập tức.


Tôi thấy rằng đây là phương pháp hiệu quả nhất khi chạy dọn dẹp trên cây thư mục ổ đĩa mạng lớn. Cảm ơn vì tiền boa.
Tonny

5

Để xóa tất cả các thư mục sẽ mất nhiều thời gian và không có nhiều thứ bạn có thể làm về nó. Những gì bạn có thể làm là lưu dữ liệu của bạn và định dạng ổ đĩa của bạn. Nó không tối ưu, nhưng nó sẽ hoạt động (và nhanh chóng).

Một tùy chọn khác có lẽ là sử dụng một số bản phân phối linux trên đĩa CD trực tiếp có thể đọc từ phân vùng NTFS. Tôi biết từ kinh nghiệm cá nhân rm -rf folderNamecó thể chạy ít nhất 2 ngày mà không gặp sự cố với hệ thống có 2GB RAM. Nó sẽ mất một lúc, nhưng ít nhất nó sẽ hoàn thành.


1
hm, Linux Tôi đang nghĩ về Cygwin. Mặc dù nó được cho là sử dụng các chức năng của Windows, nhưng chỉ cần tự hỏi liệu nó sẽ làm cho bất kỳ sự khác biệt trong trường hợp. Tôi sẽ thử nó.
Jackey Cheung

1
bạn có thể sử dụng git bash
hạt mưa

4

Erm .. Tôi không muốn biết làm thế nào bạn tạo ra rất nhiều.

Điều đang xảy ra là Explorer đang cố gắng liệt kê từng tệp và lưu trữ thông tin trong bộ nhớ trước khi bắt đầu xóa. Và rõ ràng là có quá nhiều.

Bạn đã thử lệnh rmdir /schưa? Miễn là nó thực sự xóa các tệp khi chúng được tìm thấy thay vì chờ đợi trên mỗi một tệp được liệt kê, nó có thể hoạt động.

Có bao nhiêu cấp thư mục con? Nếu chỉ có một hoặc một số số thấp khác, thì một tệp bó nhanh được đệ quy thủ công có thể hoạt động.

Bất kỳ phương pháp sẽ mất một thời gian, mặc dù.


Dĩ nhiên, ngoài đề xuất định dạng lại của soandos. Điều đó sẽ nhanh, nhưng nếu đây là ổ đĩa hệ thống của bạn, bạn sẽ phải cài đặt lại Windows.
Bob

Tôi khá chắc chắn rằng việc liệt kê phải diễn ra, chỉ để chương trình biết phải xóa cái gì tiếp theo. rmdir không thể xóa các tập tin khi chúng được tìm thấy, vì nó bắt đầu từ đầu và phải di chuyển bằng cách nào đó. Câu hỏi duy nhất là nó lưu trữ bao nhiêu thông tin.
soandos

@soandos Explorer đếm từng tập tin. Tôi đã suy nghĩ một số phương pháp thực hiện kiểu liệt kê DFS: đi càng xa càng tốt xuống một nhánh, xóa khi nó chạm vào một tập tin, trước khi quay trở lại. Nói cách khác, đệ quy, đó là những gì rm -rflàm. Điều đó làm việc tốt nhất với các cấu trúc thư mục tương đối nông. Tôi không chắc chắn nếu rmdir /slàm điều này. Nó nên .
Bob

1
@JackeyCheung rmdir /?: /s Removes all directories and files in the specified directory in addition to the directory itself. Used to remove a directory tree.Nói cách khác, /scờ cũng xóa các tệp. Bạn đã sử dụng delnhư thế nào? Và phải, tốt hơn là chỉ sử dụng rm -rfnhư soandos đề xuất.
Bob

1
@JackeyCheung: bạn sai rồi. Nếu bạn cung cấp cho rmdir cờ / s, nó sẽ xóa các tệp cũng như các thư mục.
Harry Johnston

4

Một nguyên nhân có thể của một vấn đề như thế này là việc cung cấp mỏng, thường được tìm thấy trong môi trường SAN. Một số ổ đĩa trạng thái rắn có thể thể hiện cùng một vấn đề. Nếu đây là trường hợp, thay đổi cấu hình này có thể giải quyết vấn đề của bạn:

fsutil behavior set DisableDeleteNotify 1

Lưu ý rằng thay đổi này có thể ảnh hưởng đến hiệu suất trên các ổ đĩa trạng thái rắn và có thể ngăn chặn việc lấy lại tự động và / hoặc thủ công các ổ đĩa SAN.



3

Có thể đó là phần mềm chống vi-rút / phần mềm chống virus của bạn tiêu thụ hết bộ nhớ và sau đó làm sập hệ thống.

Bản thân Windows không gặp vấn đề gì khi xóa số lượng tệp khổng lồ, mặc dù nó chắc chắn chậm hơn so với thao tác tương tự trên hầu hết các hệ thống tệp không phải của Microsoft.


Điểm hay! Chắc chắn đáng xem.
Jackey Cheung

Tôi đã tắt phần mềm chống vi-rút và bộ nhớ vẫn bị ăn mòn như trước.
Jackey Cheung

Tắt phần mềm chống vi-rút không giúp giải phóng bộ nhớ sau khi quá trình bị dừng.
Jackey Cheung

@JackeyCheung: Chương trình chống vi-rút nào? Một số không thực sự tắt hoàn toàn ...
Ben Voigt

2

Một vấn đề bạn có thể gặp phải là thư mục không được nén khi bạn xóa một tệp / thư mục, vì vậy nếu bạn có một thư mục chứa 1 triệu tệp trong đó và xóa 500k đầu tiên trong số đó. Có một tấn các khối ở đầu thư mục của bạn dành cho tất cả các ý định trống.

NHƯNG, explorer và một dấu nhắc lệnh vẫn phải xem qua các khối đó trong trường hợp có tệp ở đó. Một cái gì đó có thể giúp là "di chuyển" một thư mục từ một nơi nào đó xuống cây sang một thư mục mới ra khỏi cơ sở của ổ đĩa, sau đó xóa thư mục mới đó. Di chuyển thư mục sẽ chỉ di chuyển con trỏ đến thư mục để nó di chuyển nhanh chóng và không thực sự di chuyển tất cả các tệp trong đó sang không gian mới trên ổ đĩa.

Một điều khác bạn có thể thử là sử dụng công cụ của bên thứ 3 như "PerfectDisk" để thu gọn các thư mục sau khi xóa một loạt các tệp.


2

Thử các cách tiếp cận khác nhau để xóa hơn 10 triệu tệp nhật ký hợp nhất, tôi nhận thấy trung bình khoảng 30 nghìn tệp có thể bị xóa trong khoảng thời gian 10 phút. Điều đó sẽ mất khoảng 55 giờ cho 10 triệu tệp ...

Sử dụng tập lệnh bên dưới, tỷ lệ xóa tăng ~ 75%. Danh sách tệp được tạo và thực thi bởi các quy trình đồng thời làm tăng hoạt động của đĩa (nhưng không tuyến tính.) Tôi đang hiển thị 4 nhánh, nhưng hai có thể đủ.

Có một tùy chọn để sử dụng PowerShell giúp giảm đáng kể thời gian cần thiết để chuẩn bị danh sách.

BTW, tôi đã thử nghiệm bằng cách sử dụng hai thao tác del trực tiếp cho phép va chạm, nhưng không giảm đáng kể thời gian xóa tổng thể so với một thao tác del đơn lẻ. Và mặc dù có thể không mong muốn tạo danh sách xóa, thời gian lưu lại là xứng đáng.

@ECHO OFF
SETLOCAL EnableDelayedExpansion

IF /I "%~1"=="timestamp" (
    CALL :ECHOTIMESTAMP
    GOTO END
)

rem directory structure to delete
SET "DELETE=c:\_delete\Content.IE5\???<<<change this>>>???"
rem primary list of discovered files to delete
SET "LIST=delete-list.txt"
rem base path for sub-lists
SET "LISTBASE=.\delete-list"
SET "TITLE=Batch Delete Process"
rem specifies number of batch delete processes to spawn
SET FORKS=4
rem when set to 1, use PowerShell for list building and delete.  Definitely improves time to build fork sublists
SET POWERSHELL=0
rem specifies max files to delete when greater than 0
SET MAXDEL=1000000

rem prompt for confirmatoin
SET /P CONT=About to delete all files and directories from !DELETE!. Continue (Y/N)?
IF /I NOT "!CONT!"=="Y" EXIT /B

CALL :ECHOTIMESTAMP

ECHO Accumulating list of files to delete...
dir /b /s "!DELETE!" > "!LIST!"

FOR /F "delims=" %%c IN ('type "!LIST!" ^| find /C ":"') DO SET "COUNT=%%c"
ECHO Discoverd !COUNT! files and directories to delete.

IF  %MAXDEL% GTR 0 IF !COUNT! GTR %MAXDEL% (
    SET COUNT=%MAXDEL%
    ECHO Limiting files/directories deletion count to  !COUNT!
)

CALL :ECHOTIMESTAMP
ECHO Preparing !FORKS! delete processes...
SET /A LIMIT=!COUNT!/!FORKS!

IF !POWERSHELL! EQU 1 (
    SET SKIP=0
    FOR /L %%n IN (1,1,!FORKS!) DO (
        SET "CURRENT=!LISTBASE!-%%n.txt"
        SET "LIST[%%n]=!CURRENT!"
        DEL /f /q "!CURRENT!" > nul 2>&1
        IF %%n EQU !FORKS! SET /A LIMIT+=!FORKS!
        SET CMD=type \"!LIST!\" ^| select -first !LIMIT! -skip !SKIP!
        powershell -command "& {!CMD!}" > "!CURRENT!"
        SET /A SKIP+=!LIMIT!
    )

) ELSE (
    rem significantly slower but no PowerShell.
    SET L=1
    SET N=!LIMIT!
    SET C=0
    FOR /F %%f  IN (!LIST!) DO (
        IF !C! LSS !COUNT! (
            IF !N! GEQ !LIMIT! (
                SET "CURRENT=!LISTBASE!-!L!.txt"
                SET "LIST[!L!]=!CURRENT!"
                DEL /f /q "!CURRENT!" > nul 2>&1
                SET /A L+=1
                SET /A N=0
            ) ELSE (
                SET /A N+=1
            )
            ECHO %%f >> "!CURRENT!"
        ) ELSE (
            GOTO ENDLIST
        )
        SET /A C+=1
    )
)
:ENDLIST

CALL :ECHOTIMESTAMP
ECHO Forking !FORKS! delete processes...
FOR /L %%t IN (1,1,!FORKS!) DO (

    SET "CURRENT=!LIST[%%t]!"
    IF !POWERSHELL! EQU 1 (
        SET "TAB=        "
        SET BLANK=!TAB!!TAB!!TAB!!TAB!!TAB!!TAB!!TAB!!TAB!
        SET BLANK=!BLANK!!BLANK!!BLANK!!BLANK!
        SET DEL_CMD=del -force -recurse -ea SilentlyContinue -path \"$_\"
        SET $W_CMD=$w=$Host.UI.RawUI.WindowSize.Width
        SET $S_CMD=$s=\"$_\";$i=[math]::max^(0,$s.length-$w^);$s=$s.substring^($i, $s.length-$i^);$s=\"$s !BLANK!\";$s=$s.substring^(0,[math]::min($w,$s.length^)^)
        SET ECHO_CMD=Write-Host \"`r$s\" -NoNewLine
        SET CMD=type \"!CURRENT!\" ^| %% {!DEL_CMD!; !$W_CMD!; !$S_CMD!; !ECHO_CMD!}
        SET CMD=powershell -command "^& {!CMD!}" ^& ECHO\ ^& "%~dpnx0" timestamp
        ECHO CMD !CMD!
    ) ELSE (
        SET LOOP=FOR /F %%%f IN ^(!CURRENT!^) DO
        SET OP=del "%%%f"
        SET CMD=@ECHO OFF ^&^& ^(!LOOP! !OP!  ^> nul 2^>^&1 ^)  ^& "%~dpnx0" timestamp
    )
    rem ECHO !CMD!
    START "!TITLE! %%t" cmd /k  !CMD!
)

GOTO END

:ECHOTIMESTAMP
SETLOCAL
    SET DATESTAMP=!DATE:~10,4!-!DATE:~4,2!-!DATE:~7,2!
    SET TIMESTAMP=!TIME:~0,2!-!TIME:~3,2!-!TIME:~6,2!
    ECHO !DATESTAMP: =0!-!TIMESTAMP: =0!
ENDLOCAL
GOTO :EOF

:END
ENDLOCAL
EXIT /B

2

Hãy thử điều này và sửa đổi khi bạn cần ..

Đó là một kịch bản được thử nghiệm trên Win2003 dựa trên Giải thíchPhân tích Kỹ thuật của Synetech đã trả lời ngày 15 tháng 10 năm 13 lúc 15:22

@echo off

rem ### USE FULL PATH AS FIRST ARGUMENT TO SCRIPT, DONT FORGET QUOTES !
rem ### If you move this script, fix script path variable...
SET STATICFULLSCRIPTPATH="D:\scripts\FOLDER"
SET SCRIPTNAME="DeleteFast.bat"

rem ### If CD fails or IF condition has problems,
rem ### and DEL or RMDIR runs, its better to be at safe place.
if not exist "%TEMP%\SAFE" mkdir "%TEMP%\SAFE"
if exist "%TEMP%\SAFE" cd /d "%TEMP%\SAFE"

rem ### Fix quote overflow
set var1="%1"
set var1=%var1:"=%

if not [%1]==[] (
    cd /d "%var1%"

    echo # KILLING F AT : "%var1%"
    rem ### uncomment to do damage! ### 
    rem # del /f/q * > nul

    for /d %%i in (*) do call "%STATICFULLSCRIPTPATH%\%SCRIPTNAME%" "%var1%\%%i"

    rem ## Finish deleting the last dir
    cd /d "%var1%\.."

echo # KILLING  DIR : "%var1%"
rem ## Remove dir.. first try
rmdir /q "%var1%"

if exist "%var1%" (
    rem ## Remove dir.. second try
    rem ## If thousands of files/dirs had permission/ownership problems, then prepare to wait a long time.
    rem ### uncomment to do damage! ### 
    rem #cmd.exe /c takeown /f "%var1%" && icacls "%var1%" /grant SOMEBODY:F

    rem ### uncomment to do damage! ### 
    rem #rmdir /s/q "%var1%"
)
)

cd /d "%STATICFULLSCRIPTPATH%"

Kiểm tra .. Có các thư mục như A1 đến A4, B1 đến B4 và C1 đến C4 được lồng khác nhau ..

Z:\>"D:\scripts\FOLDER\DeleteFast.bat" "D:\scripts\TESTF\DIRS"
# KILLING F AT : "D:\scripts\TESTF\DIRS"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1\B1"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1\B1\C 1"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1\B1\C 1"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1\B1"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1\B2"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1\B2\C 2"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1\B2\C 2"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1\B2"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A2"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A2\B3"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A2\B3\C 3"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A2\B3\C 3"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A2\B3"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A2"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A3"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A3\B4"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A3\B4\C 4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A3\B4\C 4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A3\B4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A3"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS"

D:\scripts\FOLDER>

Tôi không thể nhận xét (trang web phàn nàn về danh tiếng của tôi), vì vậy tôi thêm nhận xét của mình vào đây ..

Giải pháp của Bjv tạo ra những người làm phim tạm thời vô dụng. Và sau đó nhắc lại lần thứ hai để thực hiện công việc thực tế. /superuser//a/892412/528695

Kịch bản ban đầu của Synetech không phù hợp với tôi. /superuser//a/416469/528695

@echo off
if not [%1]==[] cd /d %1
echo "%1"
for /d %%i in (*) do call %0 "%%i"

Các kết quả..

Z:\>C:\privscripts\TESTF\DeleteFastORIGINAL.bat "C:\privscripts\TESTF\DIRS"
""C:\privscripts\TESTF\DIRS""
""A1""
""B1""
""C1""
The system cannot find the path specified.
""B2""
The system cannot find the path specified.
""A2""
The system cannot find the path specified.
""A3""
The system cannot find the path specified.
""A4""

C:\privscripts\TESTF\DIRS\A1\B1\C1>

Tôi có thể xác minh rằng @ user4350129 là chính xác khi anh ta nói rằng tập lệnh của Synetech không hoạt động - Tôi đã có hành vi tương tự trên hộp Win7x64 của mình.
leinad13

Chết tiệt kịch bản của tôi cũng không hoàn hảo, các vấn đề với nếu thiếu arg và trích dẫn tràn lệnh đã phá vỡ các lệnh anc icacls .. tôi cũng chỉ kiểm tra các thư mục không phải tệp .. Tôi đã sửa các vấn đề đó .. đăng bài, nhưng luôn kiểm tra trước khi bạn sử dụng.
EO

2

Tôi đã gặp vấn đề tương tự trước đây chỉ với 10 triệu tệp nhưng trong máy chủ 2003, để xóa các tệp tôi đã sử dụng máy chủ / máy khách ftp và để máy khách xóa các tệp và thư mục. Đó là một giải pháp chậm nhưng nó hoạt động hoàn hảo.

Có lẽ bạn sẽ gặp vấn đề thứ hai với MFT ở NTFS không có giải pháp, MFT là một mảng trong win 2003 (Tôi không chắc Microsoft có giải pháp nào sau win 2003 không) đang lưu trữ tất cả các tệp theo cách tăng dần Với hàng nghìn tệp có kích thước sẽ rất điên rồ, trong trường hợp của tôi, MFT có 17 triệu bản ghi và kích thước của MFT là khoảng 19 GB chỉ với 45000 tệp, tôi đã thử nghiệm trong các hệ thống khác và có vẻ như 1 triệu bản ghi MFT sẽ khoảng 1 GB.

Bạn có thể kiểm tra trạng thái của MFT bằng lệnh này:

defrag C: /a /v
  • C: - thư đơn vị
  • /a - phân tích
  • /v - dài dòng

Một giải pháp phức tạp khác, vì không có công cụ nào có thể thu nhỏ MFT, các công cụ chỉ điền 0 tên của các tệp và thuộc tính nhưng không có gì khác, nhưng bạn có thể sử dụng trình chuyển đổi VMware hoặc một loại P2V khác và tạo một máy ảo dựa trên Máy chủ của bạn, theo cách đó bạn sẽ khắc phục tất cả các sự cố liên quan đến MFT, tôi chưa bao giờ thử nghiệm chuyển đổi từ V2P, bây giờ tôi chỉ làm việc trong môi trường ảo, nhưng tôi đã thấy nhiều thông tin về nó trên internet.

Chiến thắng năm 2003 hiện đang hoạt động hoàn hảo, kích thước của MFT là 40 MB và mọi thứ đều ổn, nếu bạn muốn tôi có thể cho bạn biết thêm về sao lưu, chống phân mảnh hoặc các tác vụ khác liên quan đến hàng triệu tệp nhỏ.



1

Vì việc xóa tất cả các tệp cùng một lúc sử dụng quá nhiều bộ nhớ, bạn cần một cách để xóa từng tệp một, nhưng với quy trình tự động. Kiểu này dễ thực hiện hơn trong trình bao kiểu Unix, vì vậy hãy sử dụng Cygwin. Lệnh sau tạo một danh sách các tệp thông thường, chuyển đổi danh sách đó thành một chuỗi các rmlệnh, sau đó đưa tập lệnh kết quả vào trình bao.

 find dir \! -type d | sed 's/^/rm /' | sh

Kịch bản đang được thực thi ngay cả khi nó đang được tạo và không có vòng lặp, vì vậy shell không (hy vọng) phải tạo bất kỳ tệp tạm thời lớn nào. Chắc chắn sẽ mất một thời gian, vì kịch bản dài hàng triệu dòng. Bạn có thể phải điều chỉnh rmlệnh (có lẽ tôi nên sử dụng -f? Nhưng bạn hiểu các tệp của bạn tốt hơn tôi) để làm cho nó hoạt động.

Bây giờ bạn không còn gì ngoài thư mục. Đây là nơi mọi thứ trở nên tồi tệ. Có thể bạn đã xóa đủ các tệp để bạn có thể làm rm -rfmà không hết bộ nhớ (và có thể nó sẽ nhanh hơn tập lệnh khác). Nếu không, chúng ta có thể điều chỉnh câu trả lời Stackoverflow này :

 find dir | perl -lne 'print tr:/::, " $_"' | sort -n | cut -d' ' -f2 | sed 's/^/rmdir /' | sh

Một lần nữa, điều chỉnh có thể là cần thiết, lần này với sort, để tránh tạo các tệp tạm thời lớn.


1

Tôi đã gặp vấn đề tương tự một thời gian trước đây. Tôi đã viết một tiện ích nhỏ thực hiện chính xác điều đó: xóa đệ quy một thư mục. Nó sẽ không liệt kê các tệp và nó sẽ không tiêu thụ nhiều bộ nhớ (O (n + m) ở mức tối đa với n = độ sâu thư mục tối đa và m = số tệp / thư mục tối đa trong một trong các thư mục con). Nó có thể xử lý các filepath dài (> 256 ký tự). Tôi muốn nhận phản hồi nếu bạn có thể giải quyết vấn đề của mình bằng cách này.

Bạn có thể tìm thấy nó ở đây: https://github.com/McNetic/fdeltree (thực thi trong thư mục phát hành)


1

Tôi tìm thấy chủ đề này đang tìm kiếm một cách tốt hơn tôi đã xóa hơn 3 triệu tệp trên một số máy chủ mà tôi hỗ trợ. Trên đây là cách vượt qua IMO phức tạp, vì vậy tôi đã kết thúc bằng cách sử dụng công cụ dòng lệnh "FORFILES" đã biết trong Windows (đây là trên Server 2003).

Dù sao, bên dưới là lệnh FORFILES tôi đã sử dụng để xóa TẤT CẢ các tệp trong một thư mục khỏi dòng lệnh.

forfiles / P "FILEER PATH CỦA BẠN TẠI ĐÂY (ví dụ: C: \ Windows \ Temp)" / C "cmd / c echo @file & del / f / q @file"

Trên đây cũng là tên của các tệp đang bị xóa trên màn hình, nhưng chỉ vì tôi muốn thấy một số tiến trình của nó thực sự đang làm gì đó, nếu bạn không lặp lại một cái gì đó giống như hộp DOS đã bị treo, thậm chí mặc dù nó đang làm việc tốt như mong đợi.

Sẽ mất một chút thời gian để bắt đầu, nghĩa là có vẻ như nó không làm gì trong một thời gian (khoảng 30m cho ~ 3 triệu tệp) nhưng cuối cùng bạn sẽ thấy tên tệp bắt đầu xuất hiện khi chúng bị xóa. Phương pháp này cũng mất nhiều thời gian để xóa các tệp (thời gian xóa thể giảm mà không có tiếng vang?), Nhưng cuối cùng nó vẫn hoạt động mà không làm sập máy, trên máy chủ của tôi đã sử dụng ~ 1,850Kb bộ nhớ trong quá trình xóa .. .

Thời lượng xóa có thể gây ra sự cố nếu máy chủ của bạn tự động đăng xuất khi bạn cần giữ chuột di chuyển (tôi khuyên bạn nên chạy với tư cách người dùng Console hoặc thông qua công cụ phần 3 như LanDesk hoặc SCCM, v.v. (hoặc MouseJiggle. exe))

Dù sao, nghĩ rằng tôi muốn chia sẻ câu trả lời của tôi, chúc may mắn tất cả!

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.