1

I want to create a batch file. When it is invoked as batch.bat MyProject or batch.bat MyProject/ it will produce the following list. Note that Dir is a sub directory of MyProject. I am using Windows 7.

Dir
Dir/SubDir1
Dir/SubDir1/SubSubDir1
Dir/SubDir1/SubSubDir2
Dir/SubDir2
Dir/SubDir2/SubSubDir1
Dir/SubDir2/SubSubDir2
Dir/SubDir2/SubSubDir3
Dir/SubDir3
Dir/SubDir4

How to write a list of directory trees to a text file?

File names must be excluded.

kiss my armpit
  • 3,413
  • 1
  • 27
  • 50
  • Does this have to be done in Batch? It would be pretty trivial in Powershell for example, but pretty hard in Batch. – RB. Aug 07 '12 at 07:47
  • Yes. In batch file only for the sake of simplicity and compatibility. – kiss my armpit Aug 07 '12 at 07:48
  • Are you able to call out to VBScript? Again, this would make things vastly simpler... – RB. Aug 07 '12 at 08:04
  • @RB.: I will avoid using other than a .bat. :-) – kiss my armpit Aug 07 '12 at 08:09
  • Fair enough - then I've posted a working answer, but I don't think it will meet your "simplicity" requirement ;-) I would strongly encourage you to use VBScript, PowerShell, or similar for this :) – RB. Aug 07 '12 at 08:23

2 Answers2

2

Ok - this should do it. It takes one argument (the root folder).

@ECHO OFF

SET root=%1

REM Get the length of the root, to make the path relative later.
REM See http://stackoverflow.com/questions/5837418/how-do-you-get-the-string-length-in-a-batch-file.
ECHO %root%>x&FOR %%? IN (x) DO SET /A rootlength=%%~z? - 1&del x 

for /F "tokens=*" %%G in ('DIR %1 /AD /S /B') do (
    CALL :PrintDirectory "%%G" %rootlength%
)

GOTO :eof

:PrintDirectory 
REM %1 Path to the folder
REM %2 Length of root string.

REM See http://www.dostips.com/DtTipsStringManipulation.php#Snippets.LeftString for
REM information on the string manipulation.

@ECHO OFF
SET start=%2
SET absPath=%1

REM Remove the path root by taking the right-hand side of the string.
CALL SET relPath=%%absPath:~%start%,-1%%

ECHO.%relPath%

You can execute it by redirecting the results to a batch file:

PrintDirectoryStructure.bat c:\MyProject > out.txt
RB.
  • 36,301
  • 12
  • 91
  • 131
  • I have tested it but some paths are missing. Have you tested it? – kiss my armpit Aug 07 '12 at 08:41
  • @GarbageCollector I've found a bug that would cause problems if the path had spaces in it. This is corrected now (note the `"tokens=*"` text I've added). Does that work for you now? If not, please give more details about what folders you are not seeing... – RB. Aug 07 '12 at 09:42
  • Invoking `PrintDirectoryStructure.bat downloads > output.txt` when I am in ``c:\users\Garbage Collector\`` produces `output.txt` with only one item even though my `downloads` contains many directories. – kiss my armpit Aug 07 '12 at 09:47
  • @GarbageCollector I've only tested it where the input is an absolute path without any spaces, and for that scenario it works fine. Any requirements you have over that are left as an exercise to the reader I'm afraid. What I've posted should be more than enough to get your script working the way you want it. – RB. Aug 07 '12 at 10:04
2

FORFILES provides a simple solution, but it is SLOW. The command works equally well from within a batch file or on the command line:

forfiles /s /p "c:\MyProject" /m * /c "cmd /v:on /c if @isdir==TRUE (set f=@relpath&echo !f:~3,-1!)" >listing.txt

If you run the command with MyProject as your current directory then you can drop the
/p "c:\MyProject" option from the command.

If you don't mind your relative paths being enclosed in quotes with .\ in the front of each path, then the solution is even simpler:

forfiles /s /p "c:\MyProject" /m * /c "cmd /c if @isdir==TRUE echo @relpath" >listing.txt
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • Worth noting, that in current version, it puts `listing.txt` into **user home directory** (i.e. `C:\Users\[username]` in Windows 7 and probably others). I was quite surprised, as I was looking at first for `listing.txt` in `c:` and in folder, which structure I want to dump. – trejder Jun 01 '14 at 10:02
  • @trejder - As written, it will create the file in the current directory of the console. You can include a path in the redirection, or you can CD or PUSHD prior to the redirected FORFILES command. – dbenham Jun 01 '14 at 13:33