Comment supprimer un grand nombre de fichiers sous Windows


22

J'ai un répertoire qui contient des millions de sous-répertoires et des milliards de fichiers. Et maintenant je dois l'effacer. Dire mille milliards, je ne parle pas de la taille du fichier, mais du nombre de fichiers.

J'ai essayé de le supprimer del/set d'utiliser l'Explorateur Windows. Aucun des deux ne peut terminer la tâche. J'ai essayé de supprimer certains des sous-répertoires un par un, et cela m'a pris des jours. Le problème que j'ai rencontré était que chaque fois, peu importe l'utilisation delou l'explorateur, je peux voir dans le Gestionnaire des tâches que l'instance de l'explorateur consomme une mémoire vertigineuse et pousse progressivement mon système à planter.

Il reste encore quelques centaines de millions de fichiers à supprimer. Y a-t-il une possibilité de réaliser avec une (ou juste quelques) commandes / actions?


[ÉDITÉ]

J'ai essayé de le faire avec Cygwin rm -fret j'ai obtenu le même résultat. Résumée comme:

  1. Peu importe l'utilisation de l'Explorateur Windows, à DELpartir de l'invite de commande ou de la rmcommande Cygwin , la mémoire système tombe progressivement à zéro et la boîte se bloquera éventuellement.

  2. Si à tout moment, avant que le système ne tombe en panne, le processus est fermé (par CTRL + C ou quoi d'autre), la boîte continuera à fonctionner normalement. Cependant, toute la mémoire utilisée ne sera PAS libérée. Dites, j'ai arrêté le processus alors que la mémoire système atteint 91%, le Gestionnaire des tâches indique: 4 Go de RAM au total, le cache est de 329 Mo et 335 Mo disponibles. Ensuite, l'utilisation de la mémoire restera autour de ce niveau jusqu'à ce que je redémarre la machine. Si j'arrête l'instance de l'explorateur dans le Gestionnaire des tâches, l'écran deviendra vierge avec la lumière du disque dur allumée en permanence et ne reviendra jamais. Normalement, lorsque j'arrête l'instance de l'explorateur dans le Gestionnaire des tâches, je peux la réinvoquer en appuyant sur Win + E, ou elle a été redémarrée automatiquement.

Eh bien, vraiment une bonne gestion de la mémoire!


[MODIFIER ENCORE] Il semble qu'une partie de la mémoire utilisée a été libérée après un long moment, mais pas tout. Une partie de la mémoire en cache et disponible est revenue dans le Gestionnaire des tâches. Je n'ai plus attendu, je ne sais pas ce qui va se passer ensuite.


Votre problème principal est donc le fait que les répertoires et sous-répertoires ne sont pas supprimés?
Sandeep Bansal

@Jackey Cheung: quelle version de Windows utilisez-vous?
Siva Charan

1
Vous pouvez écrire un script batch qui supprime les fichiers de manière réticente, non pas à partir du niveau supérieur mais par exemple au cinquième niveau de la structure des dossiers. Cela diviserait le travail en de nombreux rm séparés et séquentiels

9
Je dois savoir, comment diable avez-vous obtenu un billion de fichiers, vraiment ...
Moab

2
Un billion de fichiers a besoin d'une table de fichiers de 1 PB. Les plus gros disques durs de nos jours sont quelques To. Comment avez-vous pu obtenir une partition aussi grosse?
user541686

Réponses:


10

Explication technique

La raison pour laquelle la plupart des méthodes posent problème est que Windows essaie d'énumérer les fichiers et les dossiers. Ce n'est pas vraiment un problème avec quelques centaines - ou même mille - fichiers / dossiers à quelques niveaux de profondeur, mais lorsque vous avez des milliards de fichiers dans des millions de dossiers à des dizaines de niveaux, cela va définitivement gâcher le système. .

Laissez-nous avoir «seulement» 100 000 000 de fichiers, et Windows utilise une structure simple comme celle-ci pour stocker chaque fichier avec son chemin (de cette façon, vous évitez de stocker chaque répertoire séparément, économisant ainsi une surcharge):

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
}

Selon qu'il utilise des caractères 8 bits ou des caractères Unicode (il utilise Unicode) et si votre système est 32 bits ou 64 bits, alors il aura besoin entre 25 Go et 49 Go de mémoire pour stocker la liste (et c'est un très structure simplifiée).

La raison pour laquelle Windows essaie d'énumérer les fichiers et les dossiers avant de les supprimer varie selon la méthode que vous utilisez pour les supprimer, mais l'Explorateur et l'interpréteur de commandes le font (vous pouvez voir un délai lorsque vous lancez la commande). Vous pouvez également voir l'activité du disque (LED HDD) clignoter lors de la lecture de l'arborescence de répertoires du lecteur.

Solution

Votre meilleur pari pour faire face à ce genre de situation est d'utiliser un outil de suppression qui supprime les fichiers et les dossiers individuellement, un par un. Je ne sais pas s'il existe des outils prêts à l'emploi pour le faire, mais il devrait être possible d'accomplir avec un simple fichier de commandes.

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

Cela permet de vérifier si un argument a été transmis. Si tel est le cas, il se transforme en répertoire spécifié (vous pouvez l'exécuter sans argument pour démarrer dans le répertoire en cours ou spécifier un répertoire - même sur un autre lecteur pour qu'il démarre là).

Ensuite, il supprime tous les fichiers du répertoire actuel. Dans ce mode, il ne doit rien énumérer et simplement supprimer les fichiers sans aspirer beaucoup de mémoire, le cas échéant.

Ensuite, il énumère les dossiers dans le répertoire en cours et s'appelle lui-même, en lui passant chaque dossier (auto) pour reculer vers le bas.

Une analyse

La raison pour laquelle cela devrait fonctionner est qu'elle n'énumère pas tous les fichiers et dossiers de l' arborescence entière . Il n'énumère aucun fichier et énumère uniquement les dossiers du répertoire actuel (plus les autres dans les répertoires parents). En supposant qu'il n'y a que quelques centaines de sous-répertoires dans un dossier donné, cela ne devrait pas être trop mauvais et nécessite certainement beaucoup moins de mémoire que les autres méthodes qui énumèrent l'arborescence entière.

Vous pouvez vous demander d'utiliser le /rcommutateur au lieu d'utiliser la récursion (manuelle). Cela ne fonctionnerait pas car, bien que le /rcommutateur effectue une récursivité, il pré-énumère l'arborescence de répertoires entière, ce qui est exactement ce que nous voulons éviter; nous voulons supprimer au fur et à mesure sans suivre.

Comparaison

Permet de comparer cette méthode aux méthodes de dénombrement complet.

Vous aviez dit que vous aviez «des millions d'annuaires»; disons 100 millions. Si l'arborescence est approximativement équilibrée et en supposant une moyenne d'environ 100 sous-répertoires par dossier, alors le répertoire imbriqué le plus profond serait d'environ quatre niveaux plus bas - en fait, il y aurait 101 010 100 sous-dossiers dans toute l'arborescence. (Amusant de voir comment 100M peut se réduire à 100 et 4.)

Étant donné que nous n'énumérons pas les fichiers, nous devons seulement garder une trace d'au plus 100 noms de répertoire par niveau, pour un maximum de 4 × 100 = 400répertoires à un moment donné.

Par conséquent, la mémoire requise devrait être de ~ 206,25 Ko, bien dans les limites de tout système moderne (ou autre).

Tester

Malheureusement (?) Je n'ai pas de système avec des milliards de fichiers dans des millions de dossiers, donc je ne suis pas en mesure de le tester (je crois qu'au dernier décompte, j'avais environ ~ 800 Ko de fichiers), donc quelqu'un d'autre devra essayer il.

Caveat

Bien sûr, la mémoire n'est pas la seule limitation. Le lecteur sera également un gros goulot d'étranglement car pour chaque fichier et dossier que vous supprimez, le système doit le marquer comme libre. Heureusement, bon nombre de ces opérations sur disque seront regroupées (mises en cache) et écrites en morceaux plutôt qu'individuellement (au moins pour les disques durs, pas pour les supports amovibles), mais cela provoquera toujours un peu de thrashing pendant la lecture du système. et écrit les données.


Je suis sûr que cela ne fonctionne pas. Je l'ai essayé. Le problème réside dans la boucle FOR. Il s'est avéré que le FOR causera le même problème que l'émission directe de DEL.
Jackey Cheung

1
Cela dépend des commutateurs que vous utilisez. Si vous avez utilisé le /rcommutateur, comme je l'ai expliqué, il essaiera d'énumérer tous les fichiers. Si vous utilisez le /dcommutateur, il énumère uniquement les dossiers du répertoire en cours. Par conséquent, sauf si vous avez un milliard de dossiers dans le répertoire en cours, cela ne devrait pas poser de problème.
Synetech

7

Je ne peux pas parler des milliers de milliards de fichiers, mais j'ai récemment supprimé un ancien partage de fichiers qui contenait environ 1,8 million de fichiers en utilisant:

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

"EmptyTMPFolder" est un répertoire local vide. l'option / MIR fera ressembler la cible à la source (vide).

Le véritable avantage de cette approche a été l'option de nouvelle tentative (/ R: 30). Cela a permis d'absorber tous les problèmes de connectivité pouvant survenir au cours de ce processus. Les suppressions locales peuvent ne pas bénéficier de cette approche.

Je n'ai pas de repères spécifiques pour comparer les temps, mais je préférerais cela à certaines des autres options suggérées b / c des options de nouvelle tentative / attente. Les suppressions ont commencé presque instantanément.


J'ai trouvé que c'est de loin la méthode la plus efficace lors de l'exécution du nettoyage sur une grande arborescence de dossiers de lecteur réseau. Merci pour le tuyau.
Tonny

5

La suppression de tous les dossiers prendra du temps et vous ne pouvez pas faire grand-chose à ce sujet. Ce que vous pouvez faire est de sauvegarder vos données et de formater votre disque. Ce n'est pas optimal, mais cela fonctionnera (et rapidement).

Une autre option consiste peut-être à utiliser une distribution Linux sur un CD live pouvant lire à partir d'une partition NTFS. Je sais par expérience personnelle qui rm -rf folderNamepeut fonctionner pendant au moins 2 jours sans planter un système avec 2 Go de RAM. Cela prendra un certain temps, mais au moins cela se terminera.


1
hm, Linux. Je pense au Cygwin. Bien qu'il soit supposé utiliser les fonctions de soulignement de Windows, je me demande simplement si cela fera une différence dans le cas. Je vais l'essayer.
Jackey Cheung le

1
vous pouvez utiliser git bash
raindrop

4

Euh .. Je ne veux pas savoir comment tu en as créé autant.

Ce qui se passe, c'est qu'Explorer essaie d'énumérer chaque fichier et de stocker les informations en mémoire avant de commencer la suppression. Et il y en a évidemment beaucoup trop.

Avez-vous essayé la commande rmdir /s? Tant qu'il supprime réellement les fichiers tels qu'ils sont trouvés plutôt que d'attendre que chacun d'eux soit énuméré, cela peut fonctionner.

Combien de niveaux de sous-répertoires existe-t-il? S'il n'y en a qu'un ou un autre petit nombre, un fichier de commandes rapide qui se répète manuellement peut fonctionner.

Cependant, toute méthode prendra un certain temps.


Mis à part la suggestion de soandos de reformater, bien sûr. Ce serait rapide, mais s'il s'agit de votre lecteur système, vous devrez réinstaller Windows.
Bob

Je suis à peu près sûr que l'énumération doit avoir lieu, juste pour que le programme sache quoi supprimer ensuite. rmdir ne peut pas supprimer les fichiers tels qu'ils sont trouvés, car il commence par le haut et doit traverser d'une manière ou d'une autre. La seule question est de savoir combien d'informations en excès il stocke.
soandos

@soandos Explorer compte chaque fichier. Je pensais à une méthode qui implémente un style d'énumération DFS: aller le plus loin possible dans une branche, supprimer quand elle frappe un fichier, avant de remonter. En d'autres termes, la récursion, c'est ce qui rm -rffait. Cela fonctionne mieux avec des structures de répertoires relativement peu profondes. Je ne sais pas si rmdir /sc'est le cas. Ça devrait .
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.En d'autres termes, l' /sindicateur supprime également les fichiers. Comment l'avez-vous utilisé del? Et oui, il serait peut-être préférable de simplement l'utiliser rm -rfcomme suggéré par soandos.
Bob

1
@JackeyCheung: vous vous trompez. Si vous donnez à rmdir l'indicateur / s, il supprime les fichiers ainsi que les répertoires.
Harry Johnston

4

Une cause possible d'un problème comme celui-ci est le provisionnement fin, généralement trouvé dans les environnements SAN. Certains disques SSD peuvent présenter le même problème. Si tel est le cas, ce changement de configuration peut résoudre votre problème:

fsutil behavior set DisableDeleteNotify 1

Notez que cette modification peut avoir un impact sur les performances des disques SSD et peut empêcher une révision automatique et / ou manuelle des disques SAN.


3

Shift+ Deleteignore la corbeille et pourrait accélérer considérablement les choses.

Si cela ne fonctionne pas (cas extrêmes), essayez Fast Folder Eraser et / ou Mass Directory Eraser


quand j'ai essayé de supprimer un grand nombre de fichiers image, oui Shift DEL est assez rapide par rapport à DEL normal, merci
V-SHY

3

Il s'agit probablement de votre antivirus / anti-programme malveillant qui consomme toute la mémoire, puis bloque le système.

Windows lui-même n'a pas de problème à supprimer un grand nombre de fichiers, bien qu'il soit certainement plus lent qu'une opération similaire sur la plupart des systèmes de fichiers non Microsoft.


Joli point! Ça vaut vraiment le coup d'oeil.
Jackey Cheung

J'ai désactivé l'antivirus et la mémoire est toujours consommée comme avant.
Jackey Cheung

La désactivation de l'antivirus n'aide pas non plus à libérer de la mémoire après l'arrêt du processus.
Jackey Cheung

@JackeyCheung: De quel programme antivirus s'agit-il? Certains ne s'éteignent pas complètement ...
Ben Voigt

2

Un problème que vous pourriez rencontrer est que le répertoire n'est pas compacté lorsque vous supprimez un fichier / dossier, donc si vous avez un dossier contenant 1 million de fichiers et supprimez les premiers 500k d'entre eux. Il y a une tonne de blocs au début de votre répertoire qui sont à toutes fins utiles vides.

MAIS, l'explorateur et une invite de commande doivent toujours parcourir ces blocs au cas où il y aurait un fichier. Quelque chose qui pourrait aider est de «déplacer» un dossier d'un endroit quelconque de l'arborescence vers un nouveau dossier hors de la base du lecteur, puis de supprimer ce nouveau dossier. Le déplacement du dossier ne fera que déplacer le pointeur vers le dossier, il devrait donc aller rapidement et ne pas déplacer réellement tous les fichiers qu'il contient vers un nouvel espace sur le lecteur.

Une autre chose que vous pouvez essayer est d'utiliser un outil tiers comme "PerfectDisk" dans les dossiers Compact après avoir supprimé un tas de fichiers.


2

En essayant diverses approches pour supprimer plus de 10 millions de fichiers journaux de fusion, j'ai remarqué qu'environ 30K fichiers en moyenne pouvaient être supprimés sur une période de 10 minutes. Cela prendrait environ 55 heures pour les 10 millions de fichiers ...

En utilisant le script ci-dessous, le taux de suppression a augmenté de ~ 75%. Les listes de fichiers sont créées et exécutées par des processus simultanés augmentant les opérations sur le disque (mais pas de manière linéaire.) Je montre 4 fourchettes, mais deux pourraient suffire.

Il existe une option pour utiliser PowerShell, ce qui réduit considérablement le temps requis pour préparer les listes.

BTW, j'ai testé en utilisant deux opérations de suppression directe permettant des collisions, mais il n'y a pas eu de réduction notable du temps de suppression global par rapport à une seule opération de suppression. Et bien qu'il ne soit peut-être pas souhaitable de créer des listes de suppression, le temps gagné en valait la peine.

@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

Essayez ceci et modifiez-le selon vos besoins.

Il s'agit d'un script testé sur Win2003 basé sur les explications et analyses techniques de Synetech, répondu le 15 octobre 13 à 15h22.

@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 .. Il existe des dossiers comme A1 à A4, B1 à B4 et C1 à C4 imbriqués différemment ..

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>

Je ne peux pas commenter (le site se plaint de ma réputation), alors j'ajoute mon commentaire ici ..

La solution de Bjv crée des listes de fichiers temporaires inutiles. Et puis les réitère une deuxième fois pour faire le travail réel. /superuser//a/892412/528695

Le script original de Synetech n'a pas fonctionné pour moi. /superuser//a/416469/528695

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

Résultats..

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>

Je peux vérifier que @ user4350129 est correct lorsqu'il dit que le script de Synetech ne fonctionne pas - j'ai eu le même comportement sur ma boîte Win7x64.
leinad13

Merde, mon script n'était pas parfait non plus, problèmes avec si arg manquant et dépassement de devis cassé les commandes icacls de récupération .. J'ai également vérifié uniquement les dossiers et non les fichiers .. J'ai résolu ces problèmes .. poste édité, mais testez toujours avant d'utiliser.
EO

2

J'ai eu des problèmes similaires il y a quelque temps avec seulement 10 millions de fichiers, mais dans un serveur 2003, pour supprimer les fichiers, j'ai utilisé un serveur / client ftp et j'ai laissé le client supprimer les fichiers et les dossiers. C'est une solution lente mais cela fonctionne parfaitement.

Vous aurez probablement un deuxième problème avec le MFT dans NTFS qui n'a pas de solution, le MFT est un tableau qui dans Win 2003 (je ne suis pas sûr que Microsoft ait une solution après Win 2003) stocke tous les fichiers de manière incrémentielle afin avec des milliards de fichiers, la taille sera folle, dans mon cas, la MFT avait 17 millions d'enregistrements et la taille de la MFT était d'environ 19 Go avec seulement 45000 fichiers, j'ai testé dans d'autres systèmes et ressemble à 1 million d'enregistrements la MFT être d'environ 1 Go.

Vous pouvez vérifier l'état du MFT avec cette commande:

defrag C: /a /v
  • C: - lettre d'unité
  • /a - analyser
  • /v - verbeux

Une autre solution délicate, car il n'y a aucun outil qui peut réduire la MFT, les outils remplissent simplement 0 le nom des fichiers et des propriétés mais rien de plus, mais vous pouvez utiliser le convertisseur VMware ou un autre type de P2V et créer une machine virtuelle basée sur votre serveur, de cette façon vous réglerez tous les problèmes liés à la MFT, je n'ai jamais testé la conversion de V2P, maintenant je travaille uniquement dans des environnements virtuels, mais j'ai vu beaucoup d'informations à ce sujet sur internet.

Cette victoire 2003 fonctionne parfaitement maintenant, la taille du MFT est de 40 Mo et tout va bien, si vous voulez, je peux vous en dire plus sur les sauvegardes, défragmentation ou autres tâches liées à des millions de petits fichiers.



1

Étant donné que la suppression des fichiers à la fois utilise trop de mémoire, vous avez besoin d'un moyen de les supprimer un à la fois, mais avec un processus automatisé. Ce genre de chose est beaucoup plus facile à faire dans un shell de style Unix, alors utilisons Cygwin. La commande suivante génère une liste de fichiers ordinaires, transforme cette liste en une séquence de rmcommandes, puis envoie le script résultant à un shell.

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

Le script est exécuté même en cours de génération, et il n'y a pas de boucles, donc le shell n'a pas (espérons-le) à créer de gros fichiers temporaires. Cela prendra certainement un certain temps, car le script comporte des millions de lignes. Vous devrez peut-être modifier la rmcommande (peut-être que j'aurais dû utiliser -f? Mais vous comprenez mieux vos fichiers que moi) pour le faire fonctionner.

Il ne vous reste plus que des répertoires. Voici où les choses deviennent difficiles. Peut-être avez-vous supprimé suffisamment de fichiers pour pouvoir vous rm -rfpasser de mémoire insuffisante (et ce sera probablement plus rapide qu'un autre script). Sinon, nous pouvons adapter cette réponse Stackoverflow :

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

Encore une fois, des ajustements peuvent être nécessaires, cette fois avec sort, pour éviter de créer d'énormes fichiers temporaires.


1

J'ai rencontré le même problème il y a quelque temps. J'ai écrit un petit utilitaire qui fait exactement cela: supprimer récursivement un répertoire. Il n'énumérera pas les fichiers et ne consommera pas beaucoup de mémoire (O (n + m) au maximum avec n = profondeur maximale du répertoire et m = nombre maximal de fichiers / répertoires dans l'un des sous-répertoires). Il peut gérer de longs chemins de fichiers (> 256 caractères). J'aimerais recevoir des commentaires si vous pouvez résoudre votre problème avec cela.

Vous pouvez le trouver ici: https://github.com/McNetic/fdeltree (exécutable dans le dossier des versions)


1

J'ai trouvé ce fil à la recherche d'un meilleur moyen que moi pour supprimer plus de 3 millions de fichiers sur plusieurs des serveurs que je supporte. Ce qui précède est bien au-dessus de l'OMI compliquée, j'ai donc fini par utiliser ma méthode connue d'utilisation de l'outil de ligne de commande "FORFILES" dans Windows (c'était sur Server 2003).

Quoi qu'il en soit, voici la commande FORFILES que j'ai utilisée pour supprimer TOUS les fichiers d'un dossier de la ligne de commande.

forfiles / P "VOTRE CHEMIN DE DOSSIER ICI (par exemple C: \ Windows \ Temp)" / C "cmd / c echo @file & del / f / q @file"

Le nom ci-dessus indique également le nom des fichiers qui sont supprimés à l'écran, mais uniquement parce que je voulais voir une certaine progression de celui-ci en train de faire quelque chose, si vous ne faites pas écho à quelque chose, il semble que la boîte DOS se soit bloquée, même bien qu'il fasse le travail OK comme prévu.

Cela prend un peu de temps pour démarrer, c'est-à-dire qu'il ne fait rien pendant un certain temps (environ 30 m pour ~ 3 millions de fichiers) mais vous devriez finalement voir les noms de fichiers commencer à apparaître lorsqu'ils sont supprimés. Cette méthode prend également beaucoup de temps pour supprimer les fichiers (le temps de suppression peut être réduit sans l'écho?), Mais cela fonctionne finalement sans planter la machine, sur les fichiers de mon serveur, j'utilisais ~ 1850 Ko de mémoire pendant le processus de suppression. .

La durée de la suppression peut provoquer un problème si vos serveurs ont une déconnexion automatique car vous devez garder la souris en mouvement (je recommanderais de fonctionner en tant qu'utilisateur de la console, ou via un outil tiers tel que LanDesk ou SCCM, etc. (ou MouseJiggle). EXE))

Quoi qu'il en soit, j'ai pensé partager ma réponse, bonne chance à tous!

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.