2013-10-03 12:50:47 +0000 2013-10-03 12:50:47 +0000
53
53

Lister les fichiers de manière récursive en indiquant uniquement le chemin d'accès complet et la taille du fichier à partir de l'invite de commande de Windows

J'essaie de générer un fichier texte contenant le nom du fichier (y compris le chemin complet) et la taille du fichier pour tous les fichiers d'un répertoire particulier et de l'un de ses sous-répertoires (c'est-à-dire de manière récursive). Idéalement, je ne veux pas de virgules dans la taille du fichier (mais je m'en contenterai !)

La commande suivante le fait mais sans la taille du fichier :

dir /b /s /a:-D > results.txt

Un exemple de sortie ressemblerait à :

C:\Users\Martin\Pictures\Table\original\PC120013.JPG 227298
C:\Users\Martin\Pictures\Table\original\PC120014.JPG 123234
C:\Users\Martin\Pictures\Table\original\PC120015.JPG 932344

Je ne pense pas que cela soit possible en utilisant uniquement dir, bien que j'aimerais qu'on me prouve que j'ai tort. Y a-t-il une autre façon de faire, en utilisant uniquement les commandes disponibles dans l'invite de commande ?

Réponses (9)

28
28
28
2013-10-03 13:44:16 +0000

Cela devrait le faire :

@echo off & for /f %a in ('dir /s /b') do echo %~fa %~za

Ce n'est pas très efficace… l'exécuter pour des dossiers contenant une tonne de fichiers peut être sommaire, alors essayez-le sur des petits dossiers d'abord.

Dans le texte d'aide “pour / ?” (j'ai utilisé “a” au lieu de “I”)

In addition, substitution of FOR variable references has been enhanced.
You can now use the following optional syntax:

%~I - expands %I removing any surrounding quotes (")
%~fI - expands %I to a fully qualified path name
%~dI - expands %I to a drive letter only
%~pI - expands %I to a path only
%~nI - expands %I to a file name only
%~xI - expands %I to a file extension only
%~sI - expanded path contains short names only
%~aI - expands %I to file attributes of file
%~tI - expands %I to date/time of file
%~zI - expands %I to size of file
%~$PATH:I - searches the directories listed in the PATH
               environment variable and expands %I to the
               fully qualified name of the first one found.
               If the environment variable name is not
               defined or the file is not found by the
               search, then this modifier expands to the
               empty string

The modifiers can be combined to get compound results:

%~dpI - expands %I to a drive letter and path only
%~nxI - expands %I to a file name and extension only
%~fsI - expands %I to a full path name with short names only
%~dp$PATH:I - searches the directories listed in the PATH
               environment variable for %I and expands to the
               drive letter and path of the first one found.
%~ftzaI - expands %I to a DIR like output line
15
15
15
2013-10-03 23:34:41 +0000

L'alternative n°1 : POUR /R est plus intuitive que la n°2 pour moi.
Alternative #2 : FOR /F corrige le problème des “espaces dans les noms” dans la suggestion de BrianAdkins.
Alternative #3 : FORFILES serait mon choix, sauf que le chemin est entre guillemets.

Brian ou d'autres gourous ont peut-être une solution plus élégante ou peuvent suggérer une douzaine d'autres solutions mais ces trois-là fonctionnent. J'ai essayé d'utiliser FOR TOKENS, mais j'ai dû ensuite enlever les en-têtes et les pieds de page, alors je suis revenu au numéro 1. J'ai également envisagé de créer un petit fichier .bat et de l'appeler, mais cela ajoute un autre fichier (bien que cela offre une plus grande flexibilité, comme le ferait une fonction).

J'ai testé toutes les alternatives avec des noms de répertoires et de fichiers avec des espaces intégrés, un nom de fichier de plus de 200 caractères, un nom de fichier sans extension, et à la racine d'un petit disque (juste pour le temps ; un peu lent – comme Brian l'a suggéré – mais la recherche dans l'explorateur Windows l'est aussi ; c'est pourquoi j'ai installé l'application de recherche Everything).

Alternative #1 : FOR /R

Best( ?) En essayant de comprendre pourquoi la solution de Brian ne fonctionnait pas pour moi, j'ai regardé HELP FOR et j'ai décidé d'essayer l'approche /R. (La création d'un fichier serait la même que dans la solution n°2. )

@echo off & for /R "c:\deletelater\folder with spaces" %A in (*.*) do echo %~fA %~zA

Exemple - Works (répertoire différent de celui ci-dessus pour démontrer la récursion)

@echo off & for /R "c:\deletelater" %A in (*.*) do echo %~fA %~zA
c:\DeleteLater\Name with Spaces.txt 19800676
c:\DeleteLater\NoSpacesLongName.txt 21745440
c:\DeleteLater\Folder with Spacesnd Name with Spaces.txt 5805492
c:\DeleteLater\Folder with SpacesndNoSpacesLongName.txt 3870322
c:\DeleteLater\FolderNoSpacesrd Name with Spaces.txt 27874695
c:\DeleteLater\FolderNoSpacesrdNoSpacesLongName.txt 28726032

Alternative #2 : FOR /F

suggérée par BrianAdkins : @echo off & for /f %a in ('dir /s /b') do echo %~fa %~za

A réponse corrigée est :

@echo off & for /f "delims=*" %A in ('dir /s /b') do echo %~fA %~zA

A réponse plus complète avec les répertoires supprimés et la sortie (annexée) à un fichier est :

@echo Results on %DATE% for %CD% >> YourDirFile.txt & echo off & for /f "delims=*" %A in ('dir /s /b /a:-d') do echo %~fA %~zA >> YourDirFile.txt

Note : “delims=*” spécifie un caractère non autorisé dans les noms de fichiers.
Note : la 2ème commande supprime également les répertoires via /a:-d.
Note : le nom de la variable FOR a été mis en majuscule pour clarifier la distinction entre les paramètres de la variable et de la variable si quelqu'un choisit des noms de variables différents.
Note : Ajouté au fichier juste pour les grins car l'OP a demandé la sortie vers un fichier.

Je suppose que je devrais vraiment vérifier le statut de l'ECHO et le réinitialiser également.

Sujet - Espaces dans les noms

La solution proposée par Brian ne gère pas les noms de fichiers et de dossiers contenant des espaces (du moins pas dans ma configuration Vista).

Exemple - Mauvais(Sans délimitation ; Inclut la suppression du répertoire par OP mais avec la taille avant et après le nom de fichier pour l'accentuation)

Nom et taille tronqués (4 fichiers sur 6 incorrects) :

@echo off & for /f %A in ('dir /s /b /a:-d') do echo %~zA %~fA %~zA
 C:\DeleteLater\Name
21745440 C:\DeleteLater\NoSpacesLongName.txt 21745440
 C:\DeleteLater\Folder
 C:\DeleteLater\Folder
 C:\DeleteLater\FolderNoSpacesrd
28726032 C:\DeleteLater\FolderNoSpacesrdNoSpacesLongName.txt 28726032

Exemple - Correct(Note sortie à l'écran, non annexée au fichier)

@echo off & for /f "delims=*" %A in ('dir /s /b /a:-d') do echo %~fA %~zA
C:\DeleteLater\Name with Spaces.txt 19800676
C:\DeleteLater\NoSpacesLongName.txt 21745440
C:\DeleteLater\Folder with Spacesnd Name with Spaces.txt 5805492
C:\DeleteLater\Folder with SpacesndNoSpacesLongName.txt 3870322
C:\DeleteLater\FolderNoSpacesrd Name with Spaces.txt 27874695
C:\DeleteLater\FolderNoSpacesrdNoSpacesLongName.txt 28726032

Alternative #3 : FORFILES (Question de citation)

Cette solution est directement issue des deux derniers exemples de la documentation FORFILES (forfiles /?).

FORFILES /S /M *.doc /C "cmd /c echo @fsize"
FORFILES /M *.txt /C "cmd /c if @isdir==FALSE notepad.exe @file"

En combinant ces exemples et en écrivant dans un fichier, on obtient (presque) la réponse :

forfiles /s /c "cmd /c if @isdir==FALSE echo @path @fsize" >>ForfilesOut.txt

Notez que le chemin est entre guillemets dans la sortie.
Peu importe que echo on ou echo off soit activé.
L'ajout d'une ligne blanche séparant chaque répertoire serait une extension triviale de la FI.

Caution : L'utilisation du masque /m *.* ne renverra pas les fichiers sans extension (comme le dernier fichier dans l'exemple) !

Aside : Cela permet d'écrire un fichier dans chaque répertoire avec le contenu de ce seul répertoire :
forfiles /s /c "cmd /c if @isdir==FALSE echo @path @fsize >>ForfilesSubOut.txt" Ce n'est pas ce que voulait l'OP mais c'est parfois pratique.

Exemple - Works (mais avec le chemin complet entre guillemets)

forfiles /s /c "cmd /c if @isdir==FALSE echo @path @fsize"

"c:\DeleteLater\Name with Spaces.txt" 19800676
"c:\DeleteLater\NoSpacesLongName.txt" 21745440
"c:\DeleteLater\Folder with Spacesnd Name with Spaces.txt" 5805492
"c:\DeleteLater\Folder with SpacesndNoSpacesLongName.txt" 3870322
"c:\DeleteLater\FolderNoSpacesrd Name with Spaces.txt" 27874695
"c:\DeleteLater\FolderNoSpacesrdNoSpacesLongName.txt" 28726032
"c:\DeleteLater\MoreFiles\A really really long file name that goes on and on 123456789 asdfghjkl zxcvnm qwertyuiop and still A really really long file name that goes on and on 123456789 qwertyuiop and still further roughly 225 characters by now.txt" 447
"c:\DeleteLater\MoreFiles\New Text Document no extension" 0

Cet exemple comprend un répertoire supplémentaire avec un nom de fichier super long et un nom de fichier sans extension.

Sujet : Chemin d'accès entre guillemets

Donc, y a-t-il un moyen facile de supprimer les guillemets indésirables( ?) selon l'exemple OP et de sauvegarder l'alternative n° 3 : FORFILES. (Question rhétorique : les guillemets sont-ils une caractéristique ou un défaut ?)

1
1
1
2018-03-23 18:47:14 +0000
powershell "dir | select name,length"

Cela peut être une tricherie sur la question des OP. Cependant, la question n'est plus pertinente sur les systèmes modernes basés sur Windows. L'alias Dir a été utilisé pour aider à établir le lien logique.

1
1
1
2014-02-12 12:47:47 +0000

Je réalise que cela nécessite une utlité supplémentaire, mais vous pouvez y parvenir assez succinctement en utilisant l'utilitaire sfk utility :

sfk cwd +run -yes "sfk list -size -tab $qfile +toclip"

sfk fromclip > C:\_temp\sfk_list_output.txt

(j'ai obtenu l'approche en utilisant sfk command chaining here )

0
0
0
2017-11-11 17:59:32 +0000

Je trouve la commande “du” assez utile et elle fonctionne aussi bien sous Windows qu'Unix (elle permet de vérifier si tous les fichiers ont été copiés lors du transfert de nombreuses données d'un PC Windows vers un serveur Web Linux) :

du -ah "C:\your_dir" > "C:\file_list.txt"

sorties :

15 C:\your_dir/.htaccess
608 C:\your_dir/folder/hello.txt
1.0 C:\your_dir/folder/subfolder/test.txt
1.0 C:\your_dir/folder/subfolder
1.2M C:\your_dir/folder/world.txt
1.2M C:\your_dir/folder
9.0 C:\your_dir/no_file_ending
11 C:\your_dir/sample document 1.txt
684K C:\your_dir/sample document 2 - äöüßÄÖÜáà.txt
1.9M C:\your_dir

Cependant, je n'ai pu voir correctement que les caractères spéciaux dans Notepad, pas dans Notepad++ (ça doit être un truc d'encodage ANSI/UTF-8, pas le temps d'analyser exactement maintenant). De plus, je n'ai pas trouvé de solution pour afficher la taille après le nom du fichier. Utilisez les options “b” ou “k” au lieu de “h” pour afficher la taille en octets ou kilo-octets. J'ai eu quelques difficultés à exécuter la commande en dehors du dossier que je veux analyser. Il est donc préférable de saisir la commande dans le bon répertoire (“C:\votre_répertoire” dans cet exemple) et de la spécifier dans la commande.

0
0
0
2016-07-14 00:19:25 +0000

Voici ce que j'ai utilisé pour localiser des fichiers vidéo divers qui prenaient trop de place sur un lecteur réseau et pour écrire les résultats dans un fichier texte sur un PC local.

Je poste ma propre réponse un peu tardive pour trois raisons. Premièrement, j'aime les réponses concises. Deuxièmement, cette seule ligne de script a fonctionné pour moi dans plusieurs contextes, y compris sur un réseau. Troisièmement, selon le commentaire potentiellement obscur de Don Vince sous la réponse de BrianAdkins, l'utilisation de jetons permet de contourner les problèmes des noms de fichiers contenant des espaces.

for /f "tokens=*" %%a in ('dir H:\*.mov H:\*.avi H:\*.wmv H:\*.mp4 /s /b') do echo %%~fa %%~za >> C:\Temp\VideoList.txt

J'ai remarqué que de très longs chemins/nom de fichiers (des centaines de caractères) peuvent aussi causer des erreurs mais la recherche ne s'arrête pas là. Cependant, le chemin d'accès n'est pas entièrement exploré pour votre ou vos cibles. Une fois que vous l'avez remarqué, vous pouvez compenser en commençant plus profondément dans la structure des dossiers pour éliminer cette erreur.

Cette page ss64 a une très bonne présentation de l'utilisation de la commande dir, listant tous les commutateurs, de nombreuses combinaisons de commutateurs, et montrant plusieurs exemples utiles de syntaxe correcte. Elle n'est pas aussi complète que les différentes communautés de Stack Exchange, mais la présentation est très claire une fois que vous êtes à l'aise avec la ligne de commande/les scripts de lot.

0
0
0
2017-01-12 13:48:02 +0000

J'y suis parvenu avec la commande suivante :

(for /R "\path\to\directory\" %A in (*.*) do echo %~fA %~zA) | findstr /v "echo"

Le résultat :

D:\Users\Natasha>(for /R ".\" %A in (*.*) do echo %~fA %~zA) | findstr /v "echo"

D:\Users\Natasha\Flowers_ (12).jpg 118886

D:\Users\Natasha\SomeFolder\data.txt 1241

D:\Users\Natasha\SomeFolder\CS\Counter-Strike_1.6.exe 272645624

P.S. Ceci est basé sur la réponse de BillR (Alternative #1). Cependant, dans mon cas, elle est suspendue avec @echo off.

-1
-1
-1
2014-09-30 03:41:04 +0000

Omettez le b dans dir /b /s /a:-D > results.txt et les résultats devraient ressembler à, (c'est-à-dire dir /s/a : -D > results.txt) :

Volume dans le lecteur H est FILES Volume Numéro de série est C9EB-112E

Répertoire des fichiers H:\Files

09/29/2014 11:36 PM 0 testing. txt 1 Fichier(s) 0 octets

Répertoire des H:\Vidéo\Action\Comix

10/06/2012 09:51 AM 184,740 file1.txt 07/20/2012 06:21 AM 864,832 file2.txt 31/08/2009 08:47 PM 606,638 file3.txt 31/08/2009 09:07 PM 160,320 file4.txt

-1
-1
-1
2018-03-22 20:22:09 +0000
where * /t

Sans être trop compliqué, cela devrait produire le résultat souhaité. Cela donnera un peu plus que ce que le PO demandait, mais j'ai pensé que cela valait la peine d'être mentionné. Ajoutez le commutateur /R pour spécifier un répertoire autre que current.