Come eliminare un numero enorme di file su Windows


22

Ho una directory che contiene milioni di sottodirectory e trilioni di file. E ora devo cancellarlo. Dicendo miliardi, non sto parlando della dimensione del file, ma del numero di file.

Ho provato a eliminarlo con del/se utilizzando Esplora risorse. Nessuno dei due può completare l'attività. Ho provato a cancellare alcune delle sottodirectory una per una e mi ci sono voluti giorni. Il problema che ho incontrato è stato che ogni volta, indipendentemente dall'utilizzo delo da Explorer, nel Task Manager posso vedere che l'istanza di explorer consuma memoria alle stelle e gradualmente spinge il mio sistema in crash.

Ci sono ancora alcune centinaia di milioni di file da eliminare. C'è qualche possibilità di realizzare con uno (o solo pochi) comandi / azioni?


[MODIFICATO]

Ho provato a farlo con Cygwin rm -fre ho ottenuto lo stesso risultato. Riassunto come:

  1. Indipendentemente dall'utilizzo di Windows Explorer, DELdal prompt dei comandi o dal comando Cygwin rm, la memoria di sistema scende gradualmente a zero e la casella si arresterà in modo anomalo.

  2. Se in qualsiasi momento, prima che il sistema fallisca, il processo viene chiuso (da CTRL + C o cos'altro), la scatola continuerà a funzionare normalmente. Tuttavia, tutta la memoria utilizzata NON verrà liberata. Dì, ho fermato il processo mentre la memoria di sistema raggiunge il 91%, Task Manager dice: 4G RAM in totale, Cache è 329M e Disponibile 335MB. Quindi l'utilizzo della memoria rimarrà su questo livello fino al riavvio della macchina. Se interrompo l'istanza di explorer in Task Manager, lo schermo si spegne sempre con la luce dell'HDD e non torna più. Normalmente, quando interrompo l'istanza di explorer in Task Manager, posso ri-invocarla premendo Win + E, oppure è stata riavviata automaticamente.

Bene, davvero bella la gestione della memoria!


[MODIFICA ANCORA] Sembra che parte della memoria utilizzata sia stata liberata dopo molto tempo, ma non tutto. Parte della memoria cache e disponibile è tornata in Task Manager. Non ho più aspettato, non sono sicuro di cosa succederà allora.


Quindi il tuo problema principale è il fatto che le directory e le sottodirectory non vengono eliminate?
Sandeep Bansal,

@Jackey Cheung: quale versione di Windows stai usando?
Siva Charan,

1
È possibile scrivere uno script batch che elimini in modo ricorsivo i file, non partendo dal livello superiore ma ad es. Dal quinto livello della struttura delle cartelle. Ciò dividerebbe il lavoro in molti 'rm's separati e sequenziali

9
Devo sapere come diavolo hai preso un trilione di file, davvero ...
Moab

2
Un trilione di file ha bisogno di una tabella di file che è 1 PB. I dischi rigidi più grandi al giorno d'oggi sono pochi TB. Come hai potuto ottenere una partizione così grande?
user541686,

Risposte:


10

Spiegazione tecnica

Il motivo per cui la maggior parte dei metodi sta causando problemi è che Windows tenta di enumerare i file e le cartelle. Questo non è un grosso problema con poche centinaia - o addirittura migliaia - file / cartelle a pochi livelli di profondità, ma quando hai migliaia di miliardi di file in milioni di cartelle che scendono a dozzine di livelli, allora questo sicuramente bloccherà il sistema .

Ti permettiamo di avere "solo" 100.000.000 di file e Windows utilizza una struttura semplice come questa per memorizzare ogni file insieme al suo percorso (in questo modo eviti di memorizzare ogni directory separatamente, risparmiando così un sovraccarico):

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
}

A seconda che utilizzi caratteri a 8 bit o caratteri Unicode (utilizza Unicode) e se il tuo sistema è a 32 o 64 bit, saranno necessari tra 25 GB e 49 GB di memoria per memorizzare l'elenco (e questo è molto struttura semplificata).

Il motivo per cui Windows tenta di enumerare i file e le cartelle prima di eliminarli varia in base al metodo utilizzato per eliminarli, ma sia Explorer che l'interprete dei comandi lo fanno (è possibile vedere un ritardo all'avvio del comando). Puoi anche vedere l'attività del disco (LED HDD) lampeggiare mentre legge l'albero delle directory dall'unità.

Soluzione

La soluzione migliore per affrontare questo tipo di situazione è utilizzare uno strumento di eliminazione che elimina i file e le cartelle singolarmente, uno alla volta. Non so se ci sono strumenti già pronti per farlo, ma dovrebbe essere possibile farlo con un semplice file batch.

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

Ciò che fa è verificare se è stato passato un argomento. In tal caso, passa alla directory specificata (è possibile eseguirlo senza un argomento per avviarlo nella directory corrente o specificare una directory, anche su un'unità diversa per avviarla da lì).

Successivamente, elimina tutti i file nella directory corrente. In questa modalità, non dovrebbe enumerare nulla ed eliminare semplicemente i file senza risucchiare molta memoria.

Quindi enumera le cartelle nella directory corrente e chiama se stessa, passando ciascuna cartella (auto) per ricorrere verso il basso.

Analisi

Il motivo per cui questo dovrebbe funzionare è perché non elenca tutti i singoli file e cartelle nell'intero albero . Non enumera alcun file e elenca solo le cartelle nella directory corrente (oltre a quelle rimanenti nelle directory principali). Supponendo che ci siano solo poche centinaia di sottodirectory in una determinata cartella, quindi questo non dovrebbe essere troppo male e certamente richiede molta meno memoria rispetto ad altri metodi che enumerano l'intero albero.

Potresti chiederti di usare l' /ropzione invece di usare la ricorsione (manuale). Ciò non funzionerebbe perché mentre lo /rswitch esegue la ricorsione, pre-enumera l'intero albero di directory che è esattamente ciò che vogliamo evitare; vogliamo eliminare mentre andiamo senza tenere traccia.

Confronto

Consente di confrontare questo metodo con i metodi di enumerazione completa.

Avevi detto di avere "milioni di directory"; diciamo 100 milioni. Se l'albero è approssimativamente bilanciato e supponendo una media di circa 100 sottodirectory per cartella, la directory nidificata più profonda sarebbe di circa quattro livelli in basso, in realtà ci sarebbero 101.010.100 sottocartelle nell'intero albero. (Divertente come 100M possono essere suddivisi in soli 100 e 4.)

Poiché non stiamo enumerando i file, dobbiamo solo tenere traccia di un massimo di 100 nomi di directory per livello, per un massimo di 4 × 100 = 400directory in qualsiasi momento.

Pertanto, il requisito di memoria dovrebbe essere ~ 206,25 KB, ben entro i limiti di qualsiasi sistema moderno (o altrimenti).

Test

Sfortunatamente (?) Non ho un sistema con trilioni di file in milioni di cartelle, quindi non sono in grado di testarlo (credo all'ultimo conteggio, avevo circa ~ 800K file), quindi qualcun altro dovrà provare esso.

Avvertimento

Naturalmente la memoria non è l'unica limitazione. L'unità sarà anche un grosso collo di bottiglia perché per ogni file e cartella che elimini, il sistema deve contrassegnarlo come libero. Per fortuna, molte di queste operazioni su disco verranno raggruppate insieme (memorizzate nella cache) e scritte in blocchi anziché singolarmente (almeno per i dischi rigidi, non per i supporti rimovibili), ma causerà comunque un bel po 'di thrashing mentre il sistema legge e scrive i dati.


Sono abbastanza sicuro che non funzioni. L'ho provato Il problema risiede nel ciclo FOR. Si è scoperto che il FOR causerà lo stesso problema dell'emissione DEL diretta.
Jackey Cheung,

1
Dipende dagli switch che usi. Se hai utilizzato l' /rinterruttore, come ho spiegato, proverà a enumerare tutti i file. Se si utilizza l' /dopzione, enumera solo le cartelle nella directory corrente, quindi a meno che non si disponga di un miliardo di cartelle nella directory corrente, non dovrebbe causare problemi.
Synetech,

7

Non riesco a parlare con i trilioni di file, ma di recente ho rovinato una vecchia condivisione di file che conteneva ~ 1,8 milioni di file usando:

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

"EmptyTMPFolder" è una directory locale vuota. l'opzione / MIR farà sembrare la destinazione come la fonte (vuota).

Il vero vantaggio di questo approccio era l'opzione di nuovo tentativo (/ R: 30). Ciò ha permesso di assorbire eventuali problemi di connettività che possono verificarsi durante questo processo. Le eliminazioni locali potrebbero non trovare beneficio in questo approccio.

Non ho benchmark specifici per confrontare i tempi, ma preferirei questo ad alcune delle altre opzioni suggerite in b / c delle opzioni riprova / attendi. Le cancellazioni sono iniziate all'istante.


Ho scoperto che questo è di gran lunga il metodo più efficiente quando si esegue la pulizia su un albero delle cartelle di unità di rete di grandi dimensioni. Grazie per il suggerimento.
Tonny,

5

Per eliminare tutte le cartelle ci vorrà molto tempo e non c'è molto da fare al riguardo. Quello che puoi fare è salvare i tuoi dati e formattare il tuo disco. Non è ottimale, ma funzionerà (e rapidamente).

Un'altra opzione è forse quella di utilizzare alcune distro linux su un CD live che può leggere da una partizione NTFS. So per esperienza personale che rm -rf folderNamepuò funzionare per almeno 2 giorni senza crash di un sistema con 2 GB di RAM. Ci vorrà un po ', ma almeno finirà.


1
hm, Linux. Sto pensando al Cygwin. Sebbene si supponga di utilizzare le funzioni di Windows sottolineate, mi chiedo solo se farà differenza nel caso. Lo proverò.
Jackey Cheung,

1
puoi usare git bash
goccia di pioggia il

4

Ehm ... non voglio sapere come ne hai creati così tanti.

Ciò che sta accadendo è che Explorer sta tentando di enumerare ogni singolo file e di archiviare le informazioni in memoria, prima che inizi l'eliminazione. E ovviamente ce ne sono troppi.

Hai provato il comando rmdir /s? Fintanto che elimina effettivamente i file così come sono stati trovati anziché attendere che tutti vengano elencati, potrebbe funzionare.

Quanti livelli di sottodirectory ci sono? Se esiste solo uno, o qualche altro numero basso, potrebbe funzionare un rapido file batch che può essere ricoverato manualmente.

Tuttavia, qualsiasi metodo richiederà del tempo.


A parte la proposta di Soandos di riformattare, ovviamente. Sarebbe veloce, ma se questa è l'unità di sistema dovrai reinstallare Windows.
Bob,

Sono abbastanza sicuro che l'enumerazione debba avvenire, solo così il programma sa cosa cancellare dopo. rmdir non può cancellare i file quando vengono trovati, poiché inizia dall'alto e deve attraversare in qualche modo. L'unica domanda è quante informazioni in eccesso memorizza.
soandos,

@soandos Explorer conta tutti i file. Stavo pensando a un metodo che implementa uno stile di enumerazione DFS: andare il più lontano possibile in un ramo, eliminando quando colpisce un file, prima di risalire. In altre parole, la ricorsione, che è ciò che rm -rffa. Funziona meglio con strutture di directory relativamente poco profonde. Non sono sicuro che lo rmdir /sfaccia. Si dovrebbe .
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.In altre parole, il /sflag rimuove anche i file. Come hai usato del? E sì, potrebbe essere meglio usare rm -rfcome suggerito da soandos.
Bob,

1
@JackeyCheung: ti sbagli. Se dai a rmdir il flag / s, elimina i file e le directory.
Harry Johnston,

4

Una possibile causa di un problema come questo è il thin provisioning, generalmente presente negli ambienti SAN. Alcune unità a stato solido potrebbero presentare lo stesso problema. In questo caso, questa modifica alla configurazione potrebbe risolvere il tuo problema:

fsutil behavior set DisableDeleteNotify 1

Questa modifica può influire sulle prestazioni delle unità a stato solido e può impedire il reinserimento automatico e / o manuale delle unità SAN.



3

Probabilmente è il tuo antivirus / antimalware che consuma tutta la memoria e quindi si arresta in modo anomalo nel sistema.

Windows stesso non ha problemi a cancellare enormi quantità di file, sebbene sia certamente più lento di un'operazione simile sulla maggior parte dei filesystem non Microsoft.


Bel punto! Vale la pena dare un'occhiata.
Jackey Cheung,

Ho disattivato l'antivirus e la memoria è stata ancora divorata come prima.
Jackey Cheung il

La disattivazione dell'antivirus non aiuta a liberare memoria dopo l'interruzione del processo.
Jackey Cheung,

@JackeyCheung: quale programma antivirus è? Alcuni in realtà non si spengono completamente ...
Ben Voigt,

2

Un problema che potresti incontrare è che la directory non viene compattata quando elimini un file / cartella, quindi se hai una cartella con 1 milione di file e ne elimini i primi 500k. Ci sono un sacco di blocchi all'inizio della directory che sono vuoti a tutti gli effetti.

MA, Explorer e un prompt dei comandi devono ancora guardare attraverso quei blocchi nel caso in cui ci sia un file lì. Qualcosa che potrebbe aiutare è "spostare" una cartella da qualche parte in giù l'albero in una nuova cartella dalla base dell'unità, quindi eliminare quella nuova cartella. Spostando la cartella, il puntatore verrà spostato nella cartella, quindi dovrebbe spostarsi rapidamente e non spostare effettivamente tutti i file al di sotto di esso nel nuovo spazio sull'unità.

Un'altra cosa che potresti provare è utilizzare uno strumento di terze parti come "PerfectDisk" per compattare le cartelle dopo aver eliminato un mucchio di file.


2

Provando vari approcci per eliminare oltre 10 milioni di file di log di fusione, ho notato che circa 30K file in media potrebbero essere eliminati in un periodo di 10 minuti. Ciò richiederebbe circa 55 ore per i 10 milioni di file ...

Utilizzando lo script seguente, il tasso di eliminazione è aumentato del ~ 75%. Gli elenchi di file vengono creati ed eseguiti da processi simultanei che aumentano le operazioni del disco (ma non in modo lineare). Sto mostrando 4 fork, ma due potrebbero essere sufficienti.

C'è un'opzione per usare PowerShell che riduce significativamente il tempo necessario per preparare gli elenchi.

A proposito, ho testato utilizzando due operazioni di cancellazione diretta che consentono collisioni, ma non si è verificata una riduzione notevole del tempo di cancellazione complessivo rispetto a una singola operazione di cancellazione. E mentre potrebbe non essere desiderabile creare elenchi di eliminazioni, il tempo risparmiato ne è valsa la pena.

@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

Prova questo e modifica come ti serve.

E 'uno script testato su Win2003 basa su di Synetech spiegazione tecnica e analisi risposto 15 ottobre '13 alle 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%"

Testrun .. Esistono cartelle come da A1 a A4, da B1 a B4 e da C1 a C4 nidificate in modo diverso.

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>

Non posso commentare (il sito si lamenta della mia reputazione), quindi aggiungo il mio commento qui ..

La soluzione di Bjv crea liste di file temporanee inutili. E poi li ripete la seconda volta per fare il lavoro vero e proprio. /superuser//a/892412/528695

La sceneggiatura originale di Synetech non ha funzionato per me. /superuser//a/416469/528695

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

Risultati ..

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>

Posso verificare che @ user4350129 sia corretto quando dice che lo script di Synetech non funziona - ho avuto lo stesso comportamento sul mio box Win7x64.
leinad13,

Dannazione, il mio script non era perfetto, problemi con se mancava arg e citando overflow, ho rotto i comandi take ic ancacacls .. Inoltre ho controllato solo le cartelle, non i file .. Ho risolto quei problemi .. pubblicato dopo la modifica, ma testalo sempre prima di usarlo.
EO,

2

Ho avuto problemi simili tempo fa con solo 10 milioni di file ma in un server 2003, per eliminare i file ho usato un server / client ftp e ho lasciato il client eliminando i file e le cartelle. È una soluzione lenta ma funziona perfettamente.

Probabilmente avrai un secondo problema con la MFT in NTFS che non ha soluzione, la MFT è un array che nella vittoria del 2003 (non sono sicuro che Microsoft abbia una soluzione dopo la vittoria del 2003) sta memorizzando tutti i file in modo incrementale, quindi con trilioni di file la dimensione sarà pazza, nel mio caso la MFT aveva 17 milioni di record e la dimensione della MFT era di circa 19 GB con soli 45000 file, ho testato in altri sistemi e sembra che per 1 milione di record la MFT sarà essere circa 1 GB.

Puoi controllare lo stato della MFT con questo comando:

defrag C: /a /v
  • C: - lettera unitaria
  • /a - analizzare
  • /v - verboso

Un'altra soluzione complicata, poiché non esiste uno strumento in grado di ridurre la MFT, gli strumenti riempiono semplicemente con 0 il nome dei file e delle proprietà, ma niente di più, ma è possibile utilizzare il convertitore VMware o un altro tipo di P2V e creare una macchina virtuale basata su il tuo server, in questo modo risolverai tutti i problemi relativi alla MFT, non ho mai testato la conversione da V2P, ora sto lavorando solo in ambienti virtuali, ma ho visto molte informazioni al riguardo su internet.

Quella vittoria del 2003 funziona perfettamente ora, la dimensione della MFT è di 40 MB e tutto è ok, se vuoi posso dirti di più su backup, deframmenti o altre attività relative a milioni di piccoli file.



1

Poiché l'eliminazione simultanea dei file utilizza troppa memoria, è necessario un modo per eliminarli uno alla volta, ma con il processo automatizzato. Questo genere di cose è molto più facile da fare in una shell in stile Unix, quindi usiamo Cygwin. Il seguente comando genera un elenco di file ordinari, trasforma tale elenco in una sequenza di rmcomandi, quindi inserisce lo script risultante in una shell.

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

Lo script viene eseguito anche mentre viene generato e non ci sono loop, quindi la shell non deve (si spera) creare file di grandi dimensioni. Ci vorrà sicuramente un po 'di tempo, poiché la sceneggiatura è lunga milioni di righe. Potresti dover modificare il rmcomando (forse avrei dovuto usarlo -f? Ma hai capito meglio i tuoi file di me) per farlo funzionare.

Ora non ti resta altro che directory. Ecco dove le cose diventano piccanti. Forse hai eliminato abbastanza file in modo da poter fare a rm -rfmeno della memoria (e probabilmente sarà più veloce di un altro script). In caso contrario, possiamo adattare questa risposta StackOverflow :

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

Ancora una volta, questa volta potrebbe essere necessario modificare sort, per evitare di creare file temporanei di grandi dimensioni.


1

Ho riscontrato lo stesso problema qualche tempo fa. Ho scritto una piccola utility che fa esattamente questo: eliminare ricorsivamente una directory. Non enumera i file e non consuma molta memoria (O (n + m) al massimo con n = profondità massima della directory e m = numero massimo di file / directory in uno dei sottodir). Può gestire percorsi di file lunghi (> 256 caratteri). Mi piacerebbe ricevere feedback se riesci a risolvere il tuo problema con questo.

Puoi trovarlo qui: https://github.com/McNetic/fdeltree (eseguibile nella cartella delle versioni)


1

Ho trovato questo thread alla ricerca di un modo migliore di quello che avevo per eliminare oltre 3 milioni di file su molti dei server che supporto. Quanto sopra è troppo complicato per IMO, quindi ho finito per usare il mio metodo noto di utilizzo dello strumento da riga di comando "FORFILES" in Windows (era su Server 2003).

Comunque, sotto è il comando FORFILES che ho usato per eliminare TUTTI i file in una cartella dalla riga di comando.

forfiles / P "IL TUO PERCORSO DI FOLDER QUI (es. C: \ Windows \ Temp)" / C "cmd / c echo @file & del / f / q @file"

Quanto sopra anche ECHO è il nome dei file che vengono eliminati sullo schermo, ma solo perché volevo vedere qualche progresso nel farlo effettivamente facendo qualcosa, se non fai eco a qualcosa sembra solo che la casella DOS sia appesa, anche anche se sta facendo il lavoro OK come previsto.

L'inizializzazione richiede un po 'di tempo, ovvero sembra che non stia facendo nulla per un po' (circa 30m per ~ 3 milioni di file) ma alla fine dovresti vedere i nomi dei file che iniziano a comparire mentre vengono eliminati. Questo metodo richiede anche molto tempo per eliminare i file (il tempo di eliminazione potrebbe essere ridotto senza l'eco?), Ma alla fine funziona senza crash della macchina, sul mio server i forfile utilizzavano ~ 1.850Kb di memoria durante il processo di eliminazione .. .

La durata dell'eliminazione può causare un problema se i server hanno la disconnessione automatica in quanto è necessario mantenere il mouse in movimento (consiglierei di eseguirlo come utente Console o tramite uno strumento di terza parte come LanDesk o SCCM ecc. (O MouseJiggle). EXE))

Comunque, ho pensato di condividere la mia risposta, buona fortuna a tutti!

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.