Comment détecter (et supprimer) un fichier s’il est vide à l’aide d’un fichier batch Windows?

Comment détecter si un fichier est vide en utilisant un fichier de commandes Windows? Je veux supprimer les journaux d’erreur s’ils sont vides.

Je suis conscient pour des solutions en boucle telles que http://anderwald.info/scripting/windows-batch-delete-all-empty-files-in-a-specified-folder/ mais je me demandais s’il y avait une solution plus élégante Si vous connaissez le fichier spécifique en question qui doit être testé, il se peut que je ne souhaite pas supprimer d’autres fichiers de zéro octet dans le dossier.

Le lien que vous avez cité a utilisé ce qui suit pour supprimer tous les fichiers de longueur 0

for /F "delims=" "%I" in ('dir /B') do if not exist "%I\" if %~zI EQU 0 del "%I" 

C’est plus compliqué et pas aussi efficace qu’il pourrait l’être. Il est beaucoup plus simple d’utiliser simplement:

 for %F in (*) do if %~zF equ 0 del "%F" 

Vous souhaitez supprimer un fichier spécifique s’il s’agit d’une longueur nulle. Remplacez simplement votre nom de fichier par le caractère générique * .

 for %F in ("yourFileName") do if %~zF equ 0 del "%F" 

Si vous allez utiliser ceci dans un fichier batch, vous devez doubler tous les pourcentages ( %%F , %%~zF )

Si vous ne souhaitez pas utiliser de boucle FOR, vous pouvez utiliser un paramètre CALL à la place – il utilise les mêmes modificateurs que les variables FOR. Cependant, CALL est plus lent que FOR (probablement pas important dans votre cas)

 @echo off call :deleteIfEmpty "yourFileName" exit /b :deleteIfEmpty if %~z1 eq 0 del %1 exit /b 

MODIFIER

J’ai déjà pensé à autre chose. Une chaîne de recherche FINDSTR de "^" correspondra à toutes les lignes d’un fichier. Mais un fichier vide n’a aucune ligne. Supprimez simplement le fichier si FINDSTR ne correspond pas à une ligne.

 >nul findstr "^" "yourFileName" || del "yourFileName" 

J’ai réussi à créer une macro capable de supprimer des fichiers vides et des dossiers vides dans une hiérarchie de dossiers.

Il m’a fallu du temps pour le jouer, mais maintenant ça marche:

 @ECHO OFF SET topLevel=%cd% FOR /D /R %%D IN (*) DO ( CD %%D FOR %%F IN (*) DO IF %%~zF EQU 0 DEL "%%F" ) CD %topLevel% FOR /F "usebackq delims=" %%D IN (`"DIR/AD/B/S|SORT/R"`) DO RD "%%D" 

Il désactive d’abord l’écho (supprimez @ECHO OFF si vous voulez lire ce qui se passe réellement). Ensuite, il stocke le dossier actuel dans la variable topLevel. Ensuite, parcourez tous les dossiers “% D” en utilisant la commande FOR dans le dossier actuel et tous les sous-dossiers. Il change le répertoire local en chacun des sous-dossiers trouvés (CD %% D). Dans chaque sous-dossier utilisant une autre boucle FOR, il recherche et supprime tous les fichiers %% F pour lesquels la taille du fichier (~ z pour %% ~ zF) est 0. Lorsque cette double boucle est terminée, tous les fichiers vides sont effectivement supprimés du disque. Maintenant, une nouvelle commande FOR est exécutée pour effectuer un RD %% D pour supprimer tous les répertoires. En raison de la sécurité du DOS, il ne supprimera que les dossiers VIDE. Les dossiers contenant des fichiers restnt intacts.

Mais bon, qui dit que vous ne pouvez pas vous améliorer une fois de plus?

J’ai refait le script une fois de plus, maintenant optimisé pour un traitement rapide :

 @ECHO OFF SET topLevel=%CD% FOR /D /R %%D IN (*) DO ( CD %%D CALL :innerLoop ) CD %topLevel% FOR /F "usebackq delims=" %%D IN (`"DIR /AD/B/S | SORT /R"`) DO RD "%%D" GOTO :break :innerLoop FOR /F "delims=" %%F IN ('DIR/B/AD/OS') DO IF %%~zF EQU 0 (DEL "%%F") ELSE (GOTO :break) :break 

Le problème avec le précédent était que les deux boucles FOR nestedes touchaient chaque fichier. Comme les fichiers vides sont rares, il n’est absolument pas nécessaire de toucher chaque fichier et c’est une perte de temps considérable. J’ai essayé de l’exécuter sur un volume de 25 To avec environ 5 millions de fichiers.

J’ai donc modifié la boucle interne pour sortinger les fichiers par taille dans une commande DIR à l’aide de l’option / OS (Ordered Size). L’option / AD ne répertorie pas les répertoires, de sorte que seuls les fichiers vrais restnt (les répertoires sont également répertoriés en tant que taille 0, c’est pourquoi j’ai ajouté ceci). Pour chaque fichier, la taille est vérifiée. Une fois qu’un fichier de plus de 0 octet est trouvé, la boucle est fermée en utilisant le GOTO: break. Comme les fichiers sont sortingés par taille, le plus petit en premier, il est possible de procéder ainsi. Un énorme timesafer!

Comme la commande DOS FOR n’a pas de moyen élégant de quitter la boucle, j’ai utilisé cette construction étrange pour appeler la boucle interne en utilisant GOTO: break.

Il semble courir quelques milliers de fois plus vite sur mon gros volume que le précédent 😉

J’espère que tu aimes!

Cordialement, Axel Mertes

PS: Le plus grand cauchemar des scripts DOS est de comprendre quand vous avez besoin de %% ou de%, ou de “etc.”

La commande forfiles pourrait être plus agréable, comme ceci:

écho

 forfiles /c "cmd /c if @fsize==0 echo @file" 

effacer

 forfiles /c "cmd /c if @fsize==0 del @file" 

Fais ce que tu veux

Je créerais normalement un fichier vbscript avec FileSystemObject qui gèrerait la détection et la suppression du fichier et l’exécuterait à partir d’un fichier de commandes.

Fichier VBScript:

 Dim oFSO Dim oFile Dim ts strFilePath = "" Set oFSO = CreateObject("Scripting.FileSystemObject") if oFSO.FileExists(strFilePath) then Set oFile = oFSO.GetFile(strFilePath) strLine = "" linecount = 0 blnShouldDelete = True Set ts = oFile.OpenAsTextStream(1, -2) Do While ts.AtEndOfStream <> True linecount = linecount + 1 strLine = ts.ReadLine if Len(strLine) > 0 then blnShouldDelete = False end if Loop ts.Close if (linecount = 0 Or linecount = 1) And blnShouldDelete = True then oFile.Delete end if end if set oFSO = Nothing 

Pour le fichier batch:

 cscript .vbs PAUSE 

simple est de trouver le nombre de lignes dans le fichier en utilisant

  findstr /R /N "^" file.txt | find /C ":" 

maintenant, si son compte est égal à zéro, supprimez en utilisant les conditions if.

vous pouvez utiliser la boucle dans les fichiers et vérifier tous les fichiers dans les dossiers