Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I am trying to generate a text file containing the filename (including full path) and file size for all files in a particular directory and any of its sub-directories (i.e. recursively). Ideally, I don't want commas in the file size (but I'll settle for them!)

The following command does it but without the file size:

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

An example output would look like:

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

I don't think this is possible using dir alone, although I would love to be proved wrong. Is there another way to do this, using only commands that are available from the Command Prompt?

share|improve this question

3 Answers 3

up vote 8 down vote accepted

This should do it:

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

It's not very efficient...running it for folders containing a ton of files may be sketchy, so try it on small folders first.

From the "for /?" help text (I used 'a' instead of '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
share|improve this answer

Alternative #1: FOR /R is more intuitive than #2 for me.
Alternative #2: FOR /F fixes the problem with "spaces in names" in BrianAdkins' suggestion.
Alternative #3: FORFILES would be my pick except that the path is in double quotes.

Brian or other gurus may have a more elegant solution or may be able to suggest a dozen other solutions but these three work. I tried using FOR TOKENS but then had to strip headers and footers so I reverted back to #1. I also considered creating a small .bat file and calling it but that adds another file (although it does provide greater flexibility, as would a function).

I tested all alternatives with directory and filenames with embedded spaces, a 200+ character filename, a filename with no extension, and on root of a small drive (just for time; a little slow -- just as Brian suggested -- but then so is searching in Windows Explorer; that is why I installed Everything search app).

Alternative #1: FOR /R

Best(?) While trying to figure out why Brian's solution didn't work for me I looked at HELP FOR and decided to try the /R approach. (Creating a file would be the same as in Alternative #2.)

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

Example - Works (different directory than above to demonstrate recursion)

@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 #2: FOR /F

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

A corrected answer is:

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

A more complete answer with directories suppressed and output (appended) to a file is:

@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=*" specifies a character not allowed in filenames.
Note: 2nd command also suppresses directories via /a:-d.
Note: Made the FOR variable name uppercase to clarify the distinction between variable and variable parameters if someone chooses different variable names.
Note: Appended to file just for grins as the OP asked for output to a file.

I suppose I should really check the status of ECHO and reset it as well.

Issue - Spaces in Names

Brian's proposed solution does not handle file and folder names containing spaces (at least not on my Vista configuration).

Example - Wrong (Without delims; Includes suppressing directory per OP but with size both before and after filename for emphasis)

Truncated Name and Size (4 of 6 files incorrect):

@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

Example - Correct (Note output to screen, not appended to file)

@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)

This solution is straight from the last two examples in the FORFILES documentation (forfiles /?).

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

Combining these examples and writing to a file yields the answer (almost):

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

Note that the path is in quotes in the output.
Does not matter whether echo on or echo off is toggled.
Adding a blank line separating each directory would be a trivial extension of the IF.

Caution: Using the mask /m *.* will not return files without extension (like last file in example)!

Aside: This writes a file in each directory with contents of just that directory:
forfiles /s /c "cmd /c if @isdir==FALSE echo @path @fsize >>ForfilesSubOut.txt" Not what the OP wanted but sometimes handy.

Example - Works (but with fullpath in quotes)

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

This example includes an extra directory with a super long filename and a filename with no extension.

Issue: Path in Quotes

So, is there an easy way to remove the unwanted(?) quotes per the OP example and save Alternative #3: FORFILES. (Rhetorical question: Are the quotes a feature or a flaw?)

share|improve this answer

I realise this requires an extra utlity, but you can achieve this fairly succinctly using the sfk utility:

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

sfk fromclip > C:\_temp\sfk_list_output.txt

(I got the approach using sfk command chaining here)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.