Reputation: 372
Following is the directory that I use.
C:\test>dir /s /b /a:d
C:\test\A
C:\test\A\a
C:\test\A\b
C:\test\A\a\a
C:\test\A\a\b
C:\test\A\a\a\20160101
C:\test\A\a\a\20160816
C:\test\A\a\b\20160101
C:\test\A\a\b\20160816
C:\test\A\b\a
C:\test\A\b\b
C:\test\A\b\a\20160101
C:\test\A\b\a\20160816
C:\test\A\b\b\20160101
C:\test\A\b\b\20160816
Using dir /s /b /a:d
gets all of folder directory.
How can I get the file list to go under 3 layer of test folder by batch file?
I would like to get the following list:
C:\test\A
C:\test\A\a
C:\test\A\b
C:\test\A\a\a
C:\test\A\a\b
C:\test\A\b\a
C:\test\A\b\b
Upvotes: 0
Views: 144
Reputation: 70923
One simple solution is to use the robocopy
command. While intended for file copy operations, it includes a /L
switch to request not to copy but to list. Adjusting the switches to remove non needed information you can use
robocopy . . /e /nfl /njh /njs /ns /lev:4 /l
This will recursively (/e
) list (/l
) all selected elements under the current folder, not showing file information (/nfl
), without job header (/njh
), without summary (/njs
), without file/size counters (/ns
) for a deep search of four levels (current folder plus the three required levels below)
The output of the robocopy
command includes some tabs/spaces at the start of the line. If you need to remove them, you can use something like
for /f "tokens=*" %a in ('robocopy . . /e /nfl /njh /njs /ns /lev:4 /l') do echo %a
Or, from a batch file
for /f "tokens=*" %%a in ('robocopy . . /e /nfl /njh /njs /ns /lev:4 /l') do echo %%a
edited If robocopy
usage is a problem (not available/allowed in your system), or you need (from comments) to limit the output to only the last level, you can use something like
@echo off
setlocal enableextensions disabledelayedexpansion
rem Retrieve folder from command line, default current folder
for /f "delims=" %%a in ("%~f1\.") do set "target=%%~fa"
echo ----------------------------------------------------------------------
rem Call subroutine searching for ALL folders up to 3 levels
call :treeDump target 3
echo ----------------------------------------------------------------------
rem Call subroutine searching for folders ONLY 3 levels deep
call :treeDump target 3 true
goto :eof
rem Recursive folder search
:treeDump targetVar maxLevel forceLevel
rem targetVar = name of variable containing the folder to iterate
rem maxLevel = how many levels to search under target
rem forceLevel = only show the last requested level
setlocal disabledelayedexpansion
rem Check we are not searching too deep
2>nul set /a "nextLevel=%~2-1", "1/(%~2+1)" || goto :eof
rem Retrieve folder to iterate
setlocal enabledelayedexpansion & for %%a in ("!%~1!") do endlocal & (
rem Determine if current level must be shown
if "%~3"=="" (
echo %%~fa
) else (
if %nextLevel% lss 0 echo %%~fa
)
rem If not at the last level, keep searching
if %nextLevel% geq 0 for /d %%b in ("%%~fa\*") do (
set "target=%%~fb"
call :treeDump target %nextLevel% "%~3"
)
)
goto :eof
It uses a recursive function that will iterate over the directories tree. For each folder found, if we are not at the required level, subfolders are enumerated and the function is called again for each of them.
Upvotes: 1
Reputation:
@echo off
cls
for /f "delims=" %%I in ('dir /s /b /ad') do (
call :countAppr "%%~I"
)
exit /b
:countAppr
set "string=%~1"
set count=0
:again
set "oldstring=%string%"
set "string=%string:*\=%"
set /a count+=1
if not "%string%" == "%oldstring%" goto :again
if %count% leq 4 echo( %~1
exit /b
Explanation:
\
appears in the folder nameTo show folder only in the folder level, change leq
to equ
. The level deep can also be changed.
Note: Some of the script is copied and edited from Stephan's answer here.
Upvotes: 1