Case Else:

/*** Code’s last stand ***/

Case Else: Killer Whales hunting off the Haida Gwaii (or Queen Charlotte Islands)

Recursion in Batch, Part 2: a tree command

May 21st, 2008 · No Comments

FileTree is a rewrite of the Tree.com command.Motivational Poster for Recursion FileTree started off as a simple example of recursion, but turned out to be 2K long–so play with it if you wish. It turned out much better than I had anticipated; and it uses some Batch geek tricks to make things work. Treeing is the quintessential recursive *thing*. Without recursion, this sort of command would likely be impossible in Batch, and pretty damn hard in other languages.

Recursion is a simple concept once it gets into your head, and there are any number of treatises about it on the web–including Recursion in Batch, Part 1: An Example–so go read that if you aren’t comfortable with it.

C:\WINDOWS\System32\cmd.exe – filetree \windows\system32\wbem
C:\test\Desktop\recurse>filetree \windows\system32\wbem

 
C:\WINDOWS\system32\wbem
╞ AutoRecover
╞ Logs
╞ mof
│ ╞ bad
│ ╘ good
╞ Performance
╞ Repository
│ ╘ FS
╘ xml
Press any key to continue . . .

 

To create a tree routine without recursion, you’d have to create large dynamic arrays, or something worse–I’ve had to do that in Wise (which has no array functionality) by appending folderspecs to a string, and keeping an eye on the length of the string, so I can shove overflow into another . . . it ain’t worth it.

@ECHO OFF
IF [%1]==[/?] (
 Echo Graphically displays the folder structure of a drive or path.
 Echo Usage: %~nx0 [/dasf] [drive:][path] [ [/dasf] [drive:][path] ...]
 Echo   /d:  show File Dates
 Echo   /a:  Show File Attributes
 Echo   /s:  Show FileSizes
 Echo   /f:  Show Files in Directories
 Echo   /t:  Use Tree.com format
 Echo   /c:  Use compact format - negates /t
 Echo.
 GOTO :EOF
)

(SET Hasfiles=) & (SET Root=)
Set Params=/
Goto :GotSwitch

:ParseParams
SHIFT
SET PARAMS=%~0
If "%PARAMS%"=="" (IF "%ROOT%"=="" (SET PARAMS=.) ELSE (GOTO :DONE))
IF "%PARAMS:~0,1%"=="/" GOTO :GOTSWITCH
IF "%PARAMS:~0,1%"=="-" GOTO :GOTSWITCH
SET Root=%PARAMS%
CALL :Root "%ROOT%"
GOTO :ParseParams
:GOTSWITCH
(SET COMPACT=) & (SET SHOWDATE=) & (SET SHOWATTRIB=) & (SET SHOWSIZES=) & (SET SHOWFILES=) & (SET TREESTYLE=)
:NEXTSWITCH
SET PARAM=%PARAMS:~0,1%
SET PARAMS=%PARAMS:~1%
IF /I [%PARAM%]==[d] SET SHOWDATE=True
IF /I [%PARAM%]==[a] SET SHOWATTRIB=True
IF /I [%PARAM%]==[s] SET SHOWSIZES=True
IF /I [%PARAM%]==[f] SET SHOWFILES=True
IF /I [%PARAM%]==[t] SET TREESTYLE=True
IF /I [%PARAM%]==[c] SET COMPACT=True
IF NOT [%PARAMS%]==[] GOTO :NEXTSWITCH
IF /I [%COMPACT%]==[True] (SET TREESTYLE=)
GOTO :ParseParams

:Done
pause
GOTO :EOF
:ROOT
ECHO.
REM ~ ECHO Showdate=%Showdate%
REM ~ ECHO SHOWATTRIB=%SHOWATTRIB%
REM ~ ECHO SHOWSIZES=%SHOWSIZES%
REM ~ ECHO SHOWFILES=%SHOWFILES%
REM ~ ECHO FileSing=%FileSing%
REM ~ ECHO FileMult=%FileMult%
REM ~ ECHO DirSing=%DirSing%
REM ~ ECHO DirMult=%DirMult%
REM ~ goto :EOF

ECHO %~f1
:WalkTree
SETLOCAL
:: Set up Remainder of switches -- ME DirSpec |[|...] FileSpec
REM ~ Echo Params: %*
IF NOT [%1]==[] PUSHD %1
SET RECURPIPE=%~2

(SET LASTDIR=) & (SET LASTFILE=)
For /D %%D in (*.*) DO SET LASTDIR=%%D
FOR %%F in (*.*) DO SET LASTFILE=%%F
REM ~ Echo LastFile=%LASTFILE%
REM ~ Echo LastDir =%LASTDIR%
REM ~ ECHO RecursivePipe %RECURPIPE% Multi %FILEMULT% single %FILESING%
IF /I [%TREESTYLE%]==[True] (
 (Set VPAD=True) & (SET PADDING=) & (SET SPC=   ) & (SET FileSing=) & (SET FileMult=) & (SET DirSing=ÀÄÄÄ) & (SET DirMult=ÃÄÄÄ) & (SET DIRPAD=®DIR¯   )
) ELSE (
 (Set VPAD=True) & (SET PADDING= ) & (SET SPC=  ) & (SET FileSing=À) & (SET FileMult=Ã) & (SET DirSing=Ô) & (SET DirMult=Æ) & (SET PipeCHR=³) & (SET DIRPAD=®DIR¯   )
)
IF /I [%COMPACT%]==[True] (Set VPAD=) & (SET PADDING=) & (SET SPC=) & (SET FileSing=À) & (SET FileMult=Ã) & (SET DirSing=Ô) & (SET DirMult=Æ) & (SET PipeCHR=³) & (SET DIRPAD=ÍÍÍÍÍ   )
IF /I NOT [%SHOWFILES%]==[True] (Set VPAD=)

IF "%TREESTYLE%"=="True" (
 IF "%LASTDIR%"=="" (
  (SET Pipe=%RECURPIPE%%FILEMULT%%SPC%) & (SET Pipend=%RECURPIPE%%FILESING%%SPC%) & (SET VPADDING=%RECURPIPE%)
 ) ELSE (
  (SET Pipe=%RECURPIPE%%PIPECHR%%SPC%) & (SET Pipend=%RECURPIPE%%PIPECHR%%SPC%) & (SET VPADDING=%RECURPIPE%%PIPECHR%)
 )
) ELSE (
 IF "%LASTDIR%"=="" (
  (SET Pipe=%RECURPIPE%%FILEMULT%) & (SET Pipend=%RECURPIPE%%FILESING%) & (SET VPADDING=%RECURPIPE%)
 ) ELSE (
  (SET Pipe=%RECURPIPE%%FILEMULT%) & (SET Pipend=%RECURPIPE%%FILEMULT%) & (SET VPADDING=%RECURPIPE%%PIPECHR%)
 )
)
IF [%3]==[] (SET Pipend=%PIPE%)

IF /I [%SHOWFILES%]==[True] FOR %%F in (*.*) DO (
 IF "%LASTFILE%"=="%%F" (CALL :PrintFile "%PIPEND%" "%%F") ELSE (CALL :PrintFile "%PIPE%" "%%F")
)

IF NOT "%LASTFILE%"=="" IF /I [%VPAD%]==[True] ECHO.%VPADDING%

(SET Pipe=%RECURPIPE%%DIRMULT%) & (Set Pipend=%RECURPIPE%%DIRSING%)
(SET Pipecarry= ) & (SET LASTFILE=)

For /D %%D in (*.*) DO if "%LASTDIR%"=="%%D" (
 CALL :PrintFile "%PIPEND%" "%%D"
 CALL :WalkTree "%%D" "%RECURPIPE%%PIPECARRY%%SPC%" "%LASTDIR%"
) ELSE (
 CALL :PrintFile "%PIPE%" "%%D"
 CALL :WalkTree "%%D" "%RECURPIPE%%PIPECHR%%SPC%" "%LASTDIR%"
)

POPD
ENDLOCAL
GOTO :EOF

:PrintFile
(SET FILESIZE=) & (Set ATTRIBS=)
(Set ATTRIBS=%~a2 )
IF [%SHOWDATE%]==[True] (Set DATTIME=%~t2 )
(Set FILESIZE=%~z2       )
SET FILESIZE=%FILESIZE:~0,7%
IF 999999 LSS %~z2 (Set FILESIZE=%~z2)
(Set FILESIZE=%FILESIZE% )
IF /I "%ATTRIBS:~0,1%"=="d" (SET FILESIZE=%DIRPAD%)
IF NOT [%SHOWSIZES%]==[True] (Set FILESIZE=)
IF NOT [%SHOWATTRIB%]==[True] (Set ATTRIBS=)
:: Files with illegal characters need to stay quoted
SET FNAME=%2
SET FNAME=%FNAME:&=%
:: Filenames with parentheses break IF blocks
IF [%FNAME%]==[%2] GOTO :DropQuotes
SET FNAME=%2
Goto :Print
:DropQuotes
SET FNAME=%~2
:Print
ECHO %~1%PADDING%%DATTIME%%ATTRIBS%%FILESIZE%%FNAME%

download filetree.bat
Originally written July 4th, 2005
Picture courtesy of The Motivator

Tags: Batch Scripts · dev · scripting

0 responses so far ↓

  • There are no comments yet...Kick things off by filling out the form below.

Leave a Comment