59 votes

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

J'essaie de générer un fichier texte contenant le nom de fichier (y compris le chemin d'accès complet) et la taille du fichier pour tous les fichiers d'un répertoire particulier et de tous 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 à ceci :

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 ce soit possible en utilisant dir seul, même si j'adorerais qu'on me prouve le contraire. Existe-t-il un autre moyen de procéder, en utilisant uniquement les commandes disponibles dans l'invite de commande ?

33voto

Brian Adkins Points 1871

Cela devrait le faire :

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

Il n'est pas très efficace... l'utiliser pour des dossiers contenant une tonne de fichiers peut être douteux, essayez-le d'abord sur des petits dossiers.

Extrait du texte d'aide "for / ?" (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

18voto

user255859 Points 1

L'alternative n°1 : FOR /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û supprimer les en-têtes et les pieds de page et je suis revenu à la solution 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 solutions avec des noms de répertoire et de fichier comportant des espaces, 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é Everything search app).

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 l'alternative #2).

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

Exemple - Travaux (répertoire différent du précédent 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 Spaces\2nd Name with Spaces.txt 5805492
c:\DeleteLater\Folder with Spaces\2ndNoSpacesLongName.txt 3870322
c:\DeleteLater\FolderNoSpaces\3rd Name with Spaces.txt 27874695
c:\DeleteLater\FolderNoSpaces\3rdNoSpacesLongName.txt 28726032

Alternative n° 2 : FOR /F

suggéré 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 plus complet la réponse avec les répertoires supprimés et la sortie (annexée) dans 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 variable et paramètres de variable si quelqu'un choisit des noms de variable différents.
Note : Ajouté au fichier juste pour le plaisir car le PO a demandé une sortie vers un fichier.

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

Question - 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 sur ma configuration Vista).

Exemple - Faux (sans délimitation ; y compris la suppression du répertoire par OP, mais avec la taille avant et après le nom de fichier pour mettre l'accent).

Nom et taille tronqués (4 des 6 fichiers 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\FolderNoSpaces\3rd
28726032 C:\DeleteLater\FolderNoSpaces\3rdNoSpacesLongName.txt 28726032

Exemple - Correct (La note est affichée à l'écran et n'est pas jointe 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 Spaces\2nd Name with Spaces.txt 5805492
C:\DeleteLater\Folder with Spaces\2ndNoSpacesLongName.txt 3870322
C:\DeleteLater\FolderNoSpaces\3rd Name with Spaces.txt 27874695
C:\DeleteLater\FolderNoSpaces\3rdNoSpacesLongName.txt 28726032

Alternative #3 : FORFILES (Quote Issue)

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 la réponse (ou presque) :

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 o echo off est basculé.
L'ajout d'une ligne vierge séparant chaque répertoire serait une extension triviale de l'IF.

Attention : Utilisation du masque /m *.* ne retournera pas les fichiers sans extension (comme le dernier fichier de l'exemple) !

Aside : Ceci écrit 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 l'OP voulait mais c'est parfois pratique.

Exemple - Travaux (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 Spaces\2nd Name with Spaces.txt" 5805492
"c:\DeleteLater\Folder with Spaces\2ndNoSpacesLongName.txt" 3870322
"c:\DeleteLater\FolderNoSpaces\3rd Name with Spaces.txt" 27874695
"c:\DeleteLater\FolderNoSpaces\3rdNoSpacesLongName.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.

Question : Le chemin dans les citations

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

3voto

Matthias Luh Points 141

Je trouve la commande "du" assez utile et elle fonctionne aussi bien sous Windows que sous Unix (je l'ai utilisée pour vérifier si tous les fichiers ont été copiés lors du transfert de beaucoup de 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 les caractères spéciaux que dans Notepad, pas dans Notepad++ (il doit s'agir d'un problème de codage ANSI/UTF-8, mais je n'ai pas le temps de l'analyser précisément pour le moment). Je n'ai pas non plus 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 en kilo-octets. J'ai eu quelques difficultés à exécuter la commande en dehors du dossier que je veux analyser. Le mieux est donc d'entrer la commande dans le bon répertoire (" C:\your_dir " dans cet exemple) et en le spécifiant dans la commande.

2voto

someguy Points 21
powershell "dir | select name,length"

C'est peut-être une tromperie par rapport à la question de l'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.

1voto

user299505 Points 61

Je réalise que cela nécessite une utlité supplémentaire. mais vous pouvez y parvenir de manière assez succincte en utilisant la fonction utilité sfk :

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

sfk fromclip > C:\_temp\sfk_list_output.txt

(J'ai obtenu cette approche en utilisant enchaînement des commandes sfk ici )

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X