This article addresses one specific use case for recursion in batch: Recursively looping through a directory (also called a folder) and its sub directories.
Normally, this is a pain, and it took me a while to come up with an algorithm that works.
For recursion to work correctly, you need:
a) Subroutines, and
b) Local variables.
CMD.EXE supports the first one, but local variables are a pain: You can only use SETLOCAL/ENDLOCAL, which prevents any information to be returned to any calling level (except the ERRORLEVEL).
Here is a solution, implemented as a script that recursively deletes empty sub directories of the current directory, and traverses all the way down the directory tree:
@echo off rem This pushd is to make sure the script always returns to rem the directory it was called from pushd . set ABORT= call :Process_Dir popd exit /b :Process_Dir rem If ABORT is set, do not continue, but unwind the call stack. rem Errorlevel 1 makes sure the rd command is not attempted if defined ABORT exit /b 1 rem First, process the subdirectories through recursion for /d %%I in (*.*) do call :Recurse "%%~I" rem If ABORT is set, do not continue, but unwind the call stack if defined ABORT exit /b 1 rem Next, count the file items in the current directory rem Actually, I am only interested if there are 0, or 1 (or more) rem items in the directory set CNT=0 for /f %%I in ('dir /b') do set CNT=1 rem Return the CNT flag as an errorlevel to the calling sub exit /b %CNT% :Recurse rem If the CD fails, set ABORT and exit immed rem !!If the following line shows &, replace it with a real ampersand - it's a rem !! limitation of the syntax highlighter on our web site cd "%~1"||(set ABORT=Y&exit /b) call :Process_Dir set RESULT=%ERRORLEVEL% if defined ABORT exit /b cd .. rem Based on the result of Process_Dir, delete the subdirectory if %RESULT% equ 0 rd "%~1" exit /b
That’s it!