我目前正在使用以下命令列出一些目录:
dir /b /s /AD > c:\temp\dir_list.txt
这几乎给了我需要的列表。但是由于某些文件夹有很多子文件夹,而我不想在我的列表中看到它们,所以数据太多了。
有没有可能将该命令的递归深度限制为3(例如)?
c:\dir_1\dir_2\dir_3\dir_foo
在上面的示例中,如果我在c:\>
执行该命令,我不想看到目录dir_foo
,而只想看到dir_n
。
也许可以不用批处理或VB脚本吗?
我目前正在使用以下命令列出一些目录:
dir /b /s /AD > c:\temp\dir_list.txt
这几乎给了我需要的列表。但是由于某些文件夹有很多子文件夹,而我不想在我的列表中看到它们,所以数据太多了。
有没有可能将该命令的递归深度限制为3(例如)?
c:\dir_1\dir_2\dir_3\dir_foo
在上面的示例中,如果我在c:\>
执行该命令,我不想看到目录dir_foo
,而只想看到dir_n
。
也许可以不用批处理或VB脚本吗?
ROBOCOPY
自Vista以来一直是标准的Windows实用工具,并可通过Windows资源套件提供给XP使用。robocopy . . /l /s /njh /njs /ns /lev:4 >c:\temp\dir_list.txt
/L :: List only - don't copy, timestamp or delete any files.
/S :: copy Subdirectories, but not empty ones.
/NJH :: No Job Header.
/NJS :: No Job Summary.
/NS :: No Size - don't log file sizes.
/LEV:n :: only copy the top n LEVels of the source directory tree.
< p > /lev:n
选项包括根目录在内,并且您需要3个子目录级别,这就是为什么我将值加1的原因。
输出并不完美,因为根文件夹包含在输出中,每个路径都包括固定宽度的前导空格。您可以使用FOR /F
方便地消除根路径以及前导空格。
(for /f "skip=2 tokens=*" %A in ('robocopy . . /l /s /njh /njs /ns /lev:4') do @echo %A) >c:\temp\dir_list.txt
ROBOCOPY
的输出包括一个初始空行,这就是为什么 skip
必须是 2 而不是 1。\
结尾。我喜欢这个功能,因为它让人很容易看出我们正在列出文件夹而不是文件。如果你真的想要消除末尾的 \
,那么可以添加一个额外的 FOR
。(for /f "skip=2 tokens=*" %A in ('robocopy . . /l /s /njh /njs /ns /lev:4') do @for %B in ("%A.") do @echo %~fB) >c:\temp\dir_list.txt
但是这个命令打起来有点麻烦。将这个技巧应用到一个实用的批处理文件中,只需要将根路径和层数作为参数即可。如果你将该命令放在批处理脚本中,请记得将百分号加倍。
@echo off
setlocal
set currentLevel=0
set maxLevel=%2
if not defined maxLevel set maxLevel=1
:procFolder
pushd %1 2>nul || exit /b
if %currentLevel% lss %maxLevel% (
for /d %%F in (*) do (
echo %%~fF
set /a currentLevel+=1
call :procFolder "%%F"
set /a currentLevel-=1
)
)
popd
广度优先版本几乎相同,只是需要额外的FOR循环。
@echo off
setlocal
set currentLevel=0
set maxLevel=%2
if not defined maxLevel set maxLevel=1
:procFolder
pushd %1 2>nul || exit /b
if %currentLevel% lss %maxLevel% (
for /d %%F in (*) do echo %%~fF
for /d %%F in (*) do (
set /a currentLevel+=1
call :procFolder "%%F"
set /a currentLevel-=1
)
)
popd
这两个脚本都需要两个参数:
arg1 = 要列出的根目录的路径
arg2 = 要列出的级别数。
因此,要列出当前目录的3个级别,您可以使用
listDirs.bat . 3
如果要列出另一个目录的5个级别,可以使用以下命令:
listDirs.bat "d:\my folder\" 5
'DIR /B /S /A:HD'
-- 这将列出当前目录下的隐藏目录。 - Chef Gladiator/A:D-S
会列出所有文件夹,但不包括系统文件夹。但是我注意到如果我添加了/S
,那么-S
将被忽略? - Chef Gladiator@echo off
setlocal
set currentLevel=0
set maxLevel=%2
if not defined maxLevel set maxLevel=1
set minLevel=%3
if not defined minLevel set minLevel=0
:procFolder
pushd %1 2>nul || exit /b
if %currentLevel% lss %maxLevel% (
for /d %%F in (*) do (
if %currentLevel% geq %minLevel% echo %%~FF
set /a currentLevel+=1
call :procFolder "%%F"
set /a currentLevel-=1
)
)
popd
要设置最低等级,只需将其作为第三个参数提供即可。
例如:要从2级到5级列出列表,您可以使用
listDirs.bat target_path 5 2
或者,您可以通过将此参数留空来从基本级别列出
listDirs.bat target_path 5
这是对dbenham(和elady)方案的小改进。它根据深度缩进输出。它显著提高了可读性。
@echo off
setlocal
set currentLevel=0
set maxLevel=%2
if not defined maxLevel set maxLevel=1
set minLevel=%3
if not defined minLevel set minLevel=0
:procFolder
pushd %1 2>nul || exit /b
set "indent=."
if %currentLevel% lss %maxLevel% (
for /d %%F in (*) do (
for /l %%i in (1,1,%currentLevel%) do echo|set /p=%indent%
if %currentLevel% geq %minLevel% echo %%~fF
set /a currentLevel+=1
call :procFolder "%%F"
set /a currentLevel-=1
)
)
popd
在 set "indent ...
中可以设置缩进字符。
我对elady的版本进行了改进:
listDirs.bat 2
(直接使用)listDirs.bat 2 0
(使用不同的最小级别,请尝试并查看)listDirs.bat 2 0 target_path
(需要时使用完整语法)@echo off
setlocal
set currentLevel=0
set maxLevel=%1
if not defined maxLevel set maxLevel=1
set minLevel=%2
if not defined minLevel set /a minLevel=%maxLevel%-1
:procFolder
pushd %3 2>nul || exit /b
if %currentLevel% lss %maxLevel% (
for /d %%F in (*) do (
if %currentLevel% geq %minLevel% echo %%~fF
set /a currentLevel+=1
call :procFolder %maxLevel% %minLevel% "%%F"
set /a currentLevel-=1
)
)
popd
set "drive=C:"
for /F "usebackq tokens=* delims=" %%a in (`PowerShell.exe -Command "&{Get-ChildItem -Path %drive% -Exclude *Recycle* -Recurse -Depth 2 -Name -Directory}"`) do (
echo.[%%a]
)
-深度2应将文件夹递归限制为从根目录开始的3个文件夹的深度。 -排除回收站不显示$Recycle.bin文件夹。 -名称使命令仅显示文件夹的裸名,而不是站点。